summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlexandros Theodotou <alex@zrythm.org>2019-07-17 12:32:47 +0100
committerAlexandros Theodotou <alex@zrythm.org>2019-07-17 12:32:47 +0100
commitb2edc0bac0dd2f3e1e95c77ed4d6eda6be82e824 (patch)
tree140c01dec1030d51798506ff98c72d2fdc5ab84d
parent7e84f6452ca37f4ef6d4c732ed30ee32fd717d9c (diff)
downloadzrythm-b2edc0bac0dd2f3e1e95c77ed4d6eda6be82e824.zip
zrythm-b2edc0bac0dd2f3e1e95c77ed4d6eda6be82e824.tar.gz
zrythm-b2edc0bac0dd2f3e1e95c77ed4d6eda6be82e824.tar.bz2
add missing copyrights, move chords and automation into regions (WIP - refactor)
-rw-r--r--.gitignore17
-rw-r--r--AUTHORS13
-rw-r--r--CHANGELOG.md10
-rw-r--r--CONTRIBUTING.md14
-rw-r--r--README.md27
-rw-r--r--THANKS9
-rw-r--r--THIRDPARTY_LICENSE129
-rw-r--r--TRANSLATORS9
-rw-r--r--data/README3
-rw-r--r--data/chat-matrix.svg20
-rw-r--r--data/meson.build18
-rw-r--r--data/midnams/MIDI.midnam565
-rw-r--r--data/osx/Info.plist.in62
-rw-r--r--data/osx/appdmg.json8
-rwxr-xr-xdata/osx/gtk3-launcher.sh172
-rw-r--r--data/osx/osx_startup_script.sh31
-rw-r--r--data/osx/zrythm-gtk3.bundle118
-rw-r--r--data/osx/zrythm.icnsbin96467 -> 0 bytes
-rw-r--r--data/settings.ini17
-rw-r--r--data/zrythm.desktop17
-rw-r--r--doc/Doxyfile-mcss.in18
-rw-r--r--doc/Doxyfile.cfg.in19
-rw-r--r--doc/cyaml_schemas.h17
-rw-r--r--doc/mainpage.h17
-rw-r--r--doc/meson.build17
-rw-r--r--doc/processing_cycle.h17
-rw-r--r--doc/release_checklist.h17
-rw-r--r--doc/weblate.h17
-rw-r--r--ext/README1
-rw-r--r--ext/audio_decoder/meson.build17
-rw-r--r--ext/libcyaml/meson.build17
-rw-r--r--ext/meson.build17
-rw-r--r--ext/midilib/meson.build17
-rw-r--r--ext/zix/meson.build17
-rw-r--r--ext/zix/zix/meson.build17
-rw-r--r--flatpak/org.zrythm.Zrythm.json.README17
-rw-r--r--inc/Wrapper.h19
-rw-r--r--inc/actions/create_automation_selections_action.h71
-rw-r--r--inc/actions/create_chord_selections_action.h71
-rw-r--r--inc/actions/dir.h21
-rw-r--r--inc/actions/duplicate_automation_selections_action.h66
-rw-r--r--inc/actions/duplicate_chord_selections_action.h66
-rw-r--r--inc/actions/move_automation_selections_action.h66
-rw-r--r--inc/actions/move_chord_selections_action.h66
-rw-r--r--inc/audio/automation_curve.h98
-rw-r--r--inc/audio/automation_point.h24
-rw-r--r--inc/audio/automation_region.h164
-rw-r--r--inc/audio/automation_track.h147
-rw-r--r--inc/audio/chord_object.h30
-rw-r--r--inc/audio/chord_region.h84
-rw-r--r--inc/audio/chord_track.h23
-rw-r--r--inc/audio/dir.h17
-rw-r--r--inc/audio/marker_track.h3
-rw-r--r--inc/audio/midi_region.h21
-rw-r--r--inc/audio/region.h109
-rw-r--r--inc/audio/track.h69
-rw-r--r--inc/audio/track_lane.h3
-rw-r--r--inc/dir.h17
-rw-r--r--inc/gui/backend/arranger_selections.h309
-rw-r--r--inc/gui/backend/automation_editor.h83
-rw-r--r--inc/gui/backend/automation_selections.h94
-rw-r--r--inc/gui/backend/chord_editor.h83
-rw-r--r--inc/gui/backend/chord_selections.h89
-rw-r--r--inc/gui/backend/clip_editor.h26
-rw-r--r--inc/gui/backend/dir.h19
-rw-r--r--inc/gui/backend/events.h4
-rw-r--r--inc/gui/backend/midi_arranger_selections.h167
-rw-r--r--inc/gui/backend/piano_roll.h4
-rw-r--r--inc/gui/backend/timeline_selections.h196
-rw-r--r--inc/gui/dir.h21
-rw-r--r--inc/gui/widgets/arranger.h183
-rw-r--r--inc/gui/widgets/audio_arranger.h41
-rw-r--r--inc/gui/widgets/automation_arranger.h101
-rw-r--r--inc/gui/widgets/automation_arranger_bg.h71
-rw-r--r--inc/gui/widgets/automation_region.h65
-rw-r--r--inc/gui/widgets/chord_arranger.h75
-rw-r--r--inc/gui/widgets/chord_arranger_bg.h71
-rw-r--r--inc/gui/widgets/chord_region.h65
-rw-r--r--inc/gui/widgets/dir.h21
-rw-r--r--inc/gui/widgets/midi_arranger.h129
-rw-r--r--inc/gui/widgets/midi_modifier_arranger.h93
-rw-r--r--inc/gui/widgets/midi_region.h13
-rw-r--r--inc/gui/widgets/timeline_arranger.h206
-rw-r--r--inc/gui/widgets/timeline_bg.h5
-rw-r--r--inc/plugins/dir.h19
-rw-r--r--inc/project.h18
-rw-r--r--inc/utils/algorithms.h129
-rw-r--r--inc/utils/arrays.h6
-rw-r--r--inc/utils/dir.h19
-rw-r--r--inc/utils/stoat.h31
-rw-r--r--inc/utils/ui.h15
-rw-r--r--meson.build17
-rw-r--r--meson_options.txt17
-rw-r--r--po/meson.build17
-rw-r--r--resources/icons/ext/Bitcoin_logo.svg14
-rw-r--r--resources/icons/ext/Liberapay_logo_v2_white-on-yellow.svg.LICENSE3
-rw-r--r--resources/icons/ext/pp-logo-200px.pngbin6454 -> 0 bytes
-rw-r--r--resources/meson.build17
-rw-r--r--resources/ui/audio_clip_editor.ui2
-rw-r--r--resources/ui/automatable_selector.ui20
-rw-r--r--resources/ui/chord_pad.ui20
-rw-r--r--resources/ui/control_room.ui20
-rw-r--r--resources/ui/donate_dialog.ui20
-rw-r--r--resources/ui/expander_box.ui20
-rw-r--r--resources/ui/glade-catalog.xml20
-rw-r--r--resources/ui/header_notebook.ui20
-rw-r--r--resources/ui/help_toolbar.ui20
-rw-r--r--resources/ui/home_toolbar.ui20
-rw-r--r--resources/ui/marker_dialog.ui20
-rw-r--r--resources/ui/piano_roll_toolbar.ui20
-rw-r--r--resources/ui/port_selector_popover.ui20
-rw-r--r--resources/ui/project_toolbar.ui20
-rw-r--r--resources/ui/route_target_selector.ui20
-rw-r--r--resources/ui/shortcuts.ui20
-rw-r--r--resources/ui/timeline_toolbar.ui20
-rw-r--r--resources/ui/track_lane.ui20
-rw-r--r--resources/ui/view_toolbar.ui20
-rwxr-xr-xscripts/collect_translatables.sh17
-rwxr-xr-xscripts/meson_post_install.py17
-rw-r--r--src/Wrapper.m19
-rw-r--r--src/actions/create_automation_selections_action.c141
-rw-r--r--src/actions/create_chord_selections_action.c135
-rw-r--r--src/actions/create_midi_arranger_selections_action.c5
-rw-r--r--src/actions/create_timeline_selections_action.c87
-rw-r--r--src/actions/delete_midi_arranger_selections_action.c3
-rw-r--r--src/actions/duplicate_automation_selections_action.c160
-rw-r--r--src/actions/duplicate_chord_selections_action.c162
-rw-r--r--src/actions/duplicate_midi_arranger_selections_action.c2
-rw-r--r--src/actions/duplicate_timeline_selections_action.c29
-rw-r--r--src/actions/meson.build17
-rw-r--r--src/actions/move_automation_selections_action.c124
-rw-r--r--src/actions/move_chord_selections_action.c124
-rw-r--r--src/actions/move_timeline_selections_action.c8
-rw-r--r--src/audio/audio_region.c3
-rw-r--r--src/audio/automation_curve.c129
-rw-r--r--src/audio/automation_point.c128
-rw-r--r--src/audio/automation_region.c474
-rw-r--r--src/audio/automation_track.c650
-rw-r--r--src/audio/automation_tracklist.c38
-rw-r--r--src/audio/channel.c5
-rw-r--r--src/audio/chord_object.c76
-rw-r--r--src/audio/chord_region.c121
-rw-r--r--src/audio/chord_track.c76
-rw-r--r--src/audio/instrument_track.c3
-rw-r--r--src/audio/marker_track.c9
-rw-r--r--src/audio/meson.build19
-rw-r--r--src/audio/midi_note.c8
-rw-r--r--src/audio/midi_region.c21
-rw-r--r--src/audio/region.c279
-rw-r--r--src/audio/routing.c3
-rw-r--r--src/audio/snap_grid.c142
-rw-r--r--src/audio/track.c167
-rw-r--r--src/audio/track_lane.c12
-rw-r--r--src/gui/backend/automation_editor.c42
-rw-r--r--src/gui/backend/automation_selections.c545
-rw-r--r--src/gui/backend/chord_editor.c41
-rw-r--r--src/gui/backend/chord_selections.c517
-rw-r--r--src/gui/backend/events.c4
-rw-r--r--src/gui/backend/meson.build4
-rw-r--r--src/gui/backend/midi_arranger_selections.c10
-rw-r--r--src/gui/backend/timeline_selections.c142
-rw-r--r--src/gui/meson.build17
-rw-r--r--src/gui/widgets/arranger.c514
-rw-r--r--src/gui/widgets/audio_arranger.c52
-rw-r--r--src/gui/widgets/automation_arranger.c961
-rw-r--r--src/gui/widgets/automation_arranger_bg.c82
-rw-r--r--src/gui/widgets/automation_curve.c16
-rw-r--r--src/gui/widgets/automation_point.c6
-rw-r--r--src/gui/widgets/automation_region.c84
-rw-r--r--src/gui/widgets/chord_arranger.c835
-rw-r--r--src/gui/widgets/chord_arranger_bg.c82
-rw-r--r--src/gui/widgets/chord_object.c2
-rw-r--r--src/gui/widgets/chord_region.c86
-rw-r--r--src/gui/widgets/dzl/README1
-rw-r--r--src/gui/widgets/dzl/meson.build17
-rw-r--r--src/gui/widgets/gtk/README1
-rw-r--r--src/gui/widgets/gtk/meson.build17
-rw-r--r--src/gui/widgets/meson.build23
-rw-r--r--src/gui/widgets/midi_arranger.c12
-rw-r--r--src/gui/widgets/midi_arranger_bg.c5
-rw-r--r--src/gui/widgets/midi_modifier_arranger.c11
-rw-r--r--src/gui/widgets/piano_roll.c2
-rw-r--r--src/gui/widgets/timeline_arranger.c529
-rw-r--r--src/gui/widgets/transport_controls.c10
-rw-r--r--src/meson.build17
-rw-r--r--src/plugins/lv2/meson.build17
-rw-r--r--src/plugins/meson.build17
-rw-r--r--src/settings/meson.build17
-rw-r--r--src/utils/meson.build17
-rw-r--r--src/utils/ui.c24
-rw-r--r--tests/audio/automation_track.c1
-rw-r--r--tests/meson.build17
-rw-r--r--tools/.clang-format17
193 files changed, 9699 insertions, 4219 deletions
diff --git a/.gitignore b/.gitignore
index c515ff8..512f1c7 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,3 +1,20 @@
+# Copyright (C) 2018-2019 Alexandros Theodotou <alex at zrythm dot org>
+#
+# This file is part of Zrythm
+#
+# Zrythm is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Affero General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# Zrythm 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 Affero General Public License for more details.
+#
+# You should have received a copy of the GNU Affero General Public License
+# along with Zrythm. If not, see <https://www.gnu.org/licenses/>.
+
# Build files
build
builddir
diff --git a/AUTHORS b/AUTHORS
index 98fb846..cce9d29 100644
--- a/AUTHORS
+++ b/AUTHORS
@@ -1,10 +1,19 @@
-Alexandros Theodotou <alex@zrythm.org>
-
Contributors:
+ Alexandros Theodotou <alex@zrythm.org>
+ * Main developer
Sascha Bast <sash@mischkonsum.org>
* Piano roll auto-scroll
Robin Gareus <robin@gareus.org>
* Routing algorithm
Georg Krause
* Forward and backward button callbacks
+
+----
+
+Copyright (C) 2019 Alexandros Theodotou
+
+Copying and distribution of this file, with or without modification,
+are permitted in any medium without royalty provided the copyright
+notice and this notice are preserved. This file is offered as-is,
+without any warranty.
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 18eeb5c..d7cffa7 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -279,3 +279,13 @@ All notable changes to this project will be documented in this file.
## [0.1.009] - 2019-03-05
- First release
+
+----
+
+Copyright (C) 2019 Alexandros Theodotou
+
+Copying and distribution of this file, with or without modification,
+are permitted in any medium without royalty provided the copyright
+notice and this notice are preserved. This file is offered as-is,
+without any warranty.
+
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index 2d4007a..aab1061 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -1,11 +1,6 @@
Contributing Guidelines
=======================
-*This file is part of Zrythm and is licensed under the
-GNU Affero General Public License version 3. You should have received
-a copy of the GNU Affero General Public License
- along with Zrythm. If not, see <https://www.gnu.org/licenses/>.*
-
# CODE STRUCTURE
.
@@ -108,3 +103,12 @@ Using g_idle_add without returning false in the GSourceFunc? Not using g_idle_ad
2. GUI widgets that exist no matter what (like the tracklist, mixer, browser, etc.) should be initialized by the UI files with no _new function. Widgets that are created dynamically like channels and tracks should have a _new function. In both cases they should have a _setup function to initialize them with data and a _refresh function to update the widget to reflect the backend data. _setup must only be called once and _refresh can be called any time, but excessive calling should be avoided on widgets with many children such as the mixer and tracklist to avoid performance issues.
Anything else just ask in the chatrooms!
+
+----
+
+Copyright (C) 2018-2019 Alexandros Theodotou
+
+Copying and distribution of this file, with or without modification,
+are permitted in any medium without royalty provided the copyright
+notice and this notice are preserved. This file is offered as-is,
+without any warranty.
diff --git a/README.md b/README.md
index 28b2c21..eb8cc6e 100644
--- a/README.md
+++ b/README.md
@@ -53,8 +53,10 @@ Alternatively if you don't want to install anything on your system you can run `
## Non-standard locations
When installing in non-standard locations, glib
-needs to find the gsettings schema. By default,
-it looks in /usr and /usr/share.
+needs to find the corresponding gsettings schema.
+At runtime, GSettings looks for schemas in the
+`glib-2.0/schemas` subdirectories of all directories
+specified in the `XDG_DATA_DIRS`.
It is possible to set
the `GSETTINGS_SCHEMA_DIR` environment variable to
`<your prefix>/share/glib-2.0/schemas` or prepend
@@ -63,14 +65,14 @@ running `<your prefix>/bin/zrythm` to make glib
use the schema installed in the custom location.
There are also translations installed in the custom
-location so XDG_DATA_DIRS might be a better idea.
+location so `XDG_DATA_DIRS` might be a better idea.
-Generally, we recommend installing under /usr or
-/usr/local (default) to avoid these problems.
+Generally, we recommend installing under `/usr/local`
+(default) or `/usr` to avoid these problems.
## Packages
-For easy package installation use the download
-links on the website or see
+For easy package installation
+see
[Installation](https://manual.zrythm.org/en/configuration/installation/intro.html) in the manual.
## Using
@@ -92,8 +94,6 @@ For any bugs please raise an issue or join a chatroom below
zrythm-dev@nongnu.org for developers, zrythm-user@nongnu.org for users
## License
-Copyright (C) 2018-2019 Alexandros Theodotou et al.
-
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
@@ -121,3 +121,12 @@ https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=LZWVK6228PQ
https://liberapay.com/Zrythm/
### Bitcoin
bc1qjfyu2ruyfwv3r6u4hf2nvdh900djep2dlk746j
+
+----
+
+Copyright (C) 2018-2019 Alexandros Theodotou
+
+Copying and distribution of this file, with or without modification,
+are permitted in any medium without royalty provided the copyright
+notice and this notice are preserved. This file is offered as-is,
+without any warranty.
diff --git a/THANKS b/THANKS
index aecac55..cb73b28 100644
--- a/THANKS
+++ b/THANKS
@@ -12,3 +12,12 @@ Thanks:
* Coming up with the Zrythm tagline
Yuri
* FreeBSD packager
+
+----
+
+Copyright (C) 2019 Alexandros Theodotou
+
+Copying and distribution of this file, with or without modification,
+are permitted in any medium without royalty provided the copyright
+notice and this notice are preserved. This file is offered as-is,
+without any warranty.
diff --git a/THIRDPARTY_LICENSE b/THIRDPARTY_LICENSE
index fea894b..267d71e 100644
--- a/THIRDPARTY_LICENSE
+++ b/THIRDPARTY_LICENSE
@@ -1,21 +1,5 @@
Third party libraries
-atk
-Upstream URL: https://developer.gnome.org/atk/
-License: LGPL2
-
-bzip2
-Upstream URL: http://sources.redhat.com/bzip2
-License: Custom BSD
-
-cairo
-Upstream URL: https://cairographics.org/
-License: LGPL
-
-croco
-Upstream URL: http://www.gnome.org/browse/libcroco
-License: LGPL
-
datrie
Upstream URL: https://linux.thai.net/projects/datrie
License: LGPL
@@ -24,102 +8,26 @@ dlfcn
Upstream URL: https://github.com/dlfcn-win32/dlfcn-win32
License: LGPL
-epoxy
-Upstream URL: https://github.com/anholt/libepoxy
-License: MIT
-
-expat
-Upstream URL: http://expat.sourceforge.net/
-License: custom
-
-libffi
-Upstream URL: http://expat.sourceforge.net/
-License: MIT
-
flac
Upstream URL: http://flac.sourceforge.net/
License: GPL
-fontconfig
-Upstream URL: https://www.freedesktop.org/wiki/Software/fontconfig/
-License: custom
-
-freetype2
-Upstream URL: https://www.freetype.org/
-License: GPL
-
-fribidi
-Upstream URL: http://fribidi.org/
-License: LGPL
-
-gcc
-Upstream URL: http://gcc.gnu.org/
-License: GPL, custom, LGPL, FDL
-
-gdk-pixbuf2
-Upstream URL: http://www.gtk.org/
-License: LGPL
-
-glib2
-Upstream URL: https://wiki.gnome.org/Projects/GLib
-License: LGPL2.1
-
-graphite
-Upstream URL: https://github.com/silnrsi/graphite
-License: GPL, custom, LGPL
-
gtk3
Upstream URL: http://www.gtk.org/
License: LGPL
-harfbuzz
-Upstream URL: https://www.freedesktop.org/wiki/Software/HarfBuzz
-License: MIT
-
-libiconv
-Upstream URL: http://www.gnu.org/software/libiconv/
-License: LGPL
-
gettext
Upstream URL: http://www.gnu.org/software/gettext/
License: GPL
-jasper
-Upstream URL: http://www.ece.uvic.ca/~mdadams/jasper
-License: custom:JasPer2.0
-
-libjpeg
-Upstream URL: http://ijg.org/
-License: custom
-
-xz
-Upstream URL: https://tukaani.org/xz
-License: GPL, custom, LGPL
-
libogg
Upstream URL: http://xiph.org/
License: BSD
-pango
-Upstream URL: http://www.pango.org/
-License: LGPL
-
-pcre
-Upstream URL: http://www.pcre.org/
-License: BSD
-
-libpng
-Upstream URL: http://www.libpng.org/pub/png/libpng.html
-License: custom
-
portaudio
Upstream URL: http://www.portaudio.com/
License: custom
-librsvg
-Upstream URL: https://wiki.gnome.org/action/show/Projects/LibRsvg
-License: LGPL
-
libsamplerate
Upstream URL: http://www.mega-nerd.com/SRC/index.html
License: BSD
@@ -128,42 +36,19 @@ libsndfile
Upstream URL: http://www.mega-nerd.com/libsndfile
License: LGPL
-libthai
-Upstream URL: https://linux.thai.net/projects/libthai
-License: LGPL
-
-libtiff
-Upstream URL: http://www.simplesystems.org/libtiff/
-License: custom
-
libvorbis
Upstream URL: http://xiph.org/
License: custom
-libxml2
-Upstream URL: http://www.xmlsoft.org/
-License: LGPL
-
lilv
Upstream URL: https://drobilla.net/software/lilv/
-License: custom:ISC
-
-serd
-Upstream URL: https://drobilla.net/software/serd/
-License: custom:ISC
+License: ISC
-sord
-Upstream URL: https://drobilla.net/software/sord/
-License: custom:ISC
+----
-sratom
-Upstream URL: https://drobilla.net/software/sratom/
-License: custom:ISC
+Copyright (C) 2019 Alexandros Theodotou
-zlib
-Upstream URL: http://www.zlib.net/
-License: custom:zlib
-
-pixman
-Upstream URL: http://xorg.freedesktop.org/
-License: custom
+Copying and distribution of this file, with or without modification,
+are permitted in any medium without royalty provided the copyright
+notice and this notice are preserved. This file is offered as-is,
+without any warranty.
diff --git a/TRANSLATORS b/TRANSLATORS
index df0220b..ae67f0d 100644
--- a/TRANSLATORS
+++ b/TRANSLATORS
@@ -16,3 +16,12 @@ Norwegian Bokmal:
Polish:
* WaldiS <admin@sto.ugu.pl>
+
+----
+
+Copyright (C) 2019 Alexandros Theodotou
+
+Copying and distribution of this file, with or without modification,
+are permitted in any medium without royalty provided the copyright
+notice and this notice are preserved. This file is offered as-is,
+without any warranty.
diff --git a/data/README b/data/README
new file mode 100644
index 0000000..e0c44e0
--- /dev/null
+++ b/data/README
@@ -0,0 +1,3 @@
+All images in this directory are licensed under a Creative Commons Attribution-ShareAlike 4.0 International License.
+
+You should have received a copy of the Creative Commons Attribution-ShareAlike 4.0 International License along with Zrythm. If not, see <https://creativecommons.org/licenses/by-sa/4.0/>
diff --git a/data/chat-matrix.svg b/data/chat-matrix.svg
deleted file mode 100644
index 9e09a58..0000000
--- a/data/chat-matrix.svg
+++ /dev/null
@@ -1,20 +0,0 @@
-<svg xmlns="http://www.w3.org/2000/svg" width="99" height="20">
-<linearGradient id="b" x2="0" y2="100%">
- <stop offset="0" stop-color="#bbb" stop-opacity=".1"/>
- <stop offset="1" stop-opacity=".1"/>
-</linearGradient>
-<mask id="a">
- <rect width="99" height="20" rx="3" fill="#fff"/>
-</mask>
-<g mask="url(#a)">
- <path fill="#555" d="M0 0h42v20H0z"/>
- <path fill="#46BC99" d="M42 0h59v20H42z"/>
- <path fill="url(#b)" d="M0 0h99v20H0z"/>
-</g>
-<g fill="#fff" text-anchor="middle" font-family="DejaVu Sans,Verdana,Geneva,sans-serif" font-size="11">
- <text x="21" y="15" fill="#010101" fill-opacity=".3">matrix</text>
- <text x="21" y="14">matrix</text>
- <text x="68.5" y="15" fill="#010101" fill-opacity=".3">join chat</text>
- <text x="68.5" y="14">join chat</text>
-</g>
-</svg>
diff --git a/data/meson.build b/data/meson.build
index 1ab1cb7..6f8759c 100644
--- a/data/meson.build
+++ b/data/meson.build
@@ -1,3 +1,20 @@
+# Copyright (C) 2019 Alexandros Theodotou <alex at zrythm dot org>
+#
+# This file is part of Zrythm
+#
+# Zrythm is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Affero General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# Zrythm 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 Affero General Public License for more details.
+#
+# You should have received a copy of the GNU Affero General Public License
+# along with Zrythm. If not, see <https://www.gnu.org/licenses/>.
+
install_data (
'org.zrythm.gschema.xml',
install_dir: schemasdir)
@@ -5,4 +22,3 @@ install_data (
'zrythm.desktop',
install_dir: join_paths (datadir, 'applications'))
-#FIXME add the windows .exe icon
diff --git a/data/midnams/MIDI.midnam b/data/midnams/MIDI.midnam
deleted file mode 100644
index bb6edc9..0000000
--- a/data/midnams/MIDI.midnam
+++ /dev/null
@@ -1,565 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!DOCTYPE MIDINameDocument PUBLIC "-//MIDI Manufacturers Association//DTD MIDINameDocument 1.0//EN" "http://www.midi.org/dtds/MIDINameDocument10.dtd">
-<MIDINameDocument>
- <!-- Originally "MIDI Manufacturers Association" and modified by myself,
- though I don't know if this document actually originated from the MMA -->
- <Author>David Robillard</Author>
- <MasterDeviceNames>
- <Manufacturer>MMA</Manufacturer>
- <Model>Generic</Model>
- <CustomDeviceMode Name="MIDI">
- <ChannelNameSetAssignments>
- <ChannelNameSetAssign Channel="1" NameSet="MIDI Voices"/>
- <ChannelNameSetAssign Channel="2" NameSet="MIDI Voices"/>
- <ChannelNameSetAssign Channel="3" NameSet="MIDI Voices"/>
- <ChannelNameSetAssign Channel="4" NameSet="MIDI Voices"/>
- <ChannelNameSetAssign Channel="5" NameSet="MIDI Voices"/>
- <ChannelNameSetAssign Channel="6" NameSet="MIDI Voices"/>
- <ChannelNameSetAssign Channel="7" NameSet="MIDI Voices"/>
- <ChannelNameSetAssign Channel="8" NameSet="MIDI Voices"/>
- <ChannelNameSetAssign Channel="9" NameSet="MIDI Voices"/>
- <ChannelNameSetAssign Channel="10" NameSet="MIDI Voices"/>
- <ChannelNameSetAssign Channel="11" NameSet="MIDI Voices"/>
- <ChannelNameSetAssign Channel="12" NameSet="MIDI Voices"/>
- <ChannelNameSetAssign Channel="13" NameSet="MIDI Voices"/>
- <ChannelNameSetAssign Channel="14" NameSet="MIDI Voices"/>
- <ChannelNameSetAssign Channel="15" NameSet="MIDI Voices"/>
- <ChannelNameSetAssign Channel="16" NameSet="MIDI Voices"/>
- </ChannelNameSetAssignments>
- </CustomDeviceMode>
- <CustomDeviceMode Name="General MIDI">
- <ChannelNameSetAssignments>
- <ChannelNameSetAssign Channel="1" NameSet="General MIDI Voices"/>
- <ChannelNameSetAssign Channel="2" NameSet="General MIDI Voices"/>
- <ChannelNameSetAssign Channel="3" NameSet="General MIDI Voices"/>
- <ChannelNameSetAssign Channel="4" NameSet="General MIDI Voices"/>
- <ChannelNameSetAssign Channel="5" NameSet="General MIDI Voices"/>
- <ChannelNameSetAssign Channel="6" NameSet="General MIDI Voices"/>
- <ChannelNameSetAssign Channel="7" NameSet="General MIDI Voices"/>
- <ChannelNameSetAssign Channel="8" NameSet="General MIDI Voices"/>
- <ChannelNameSetAssign Channel="9" NameSet="General MIDI Voices"/>
- <ChannelNameSetAssign Channel="10" NameSet="General MIDI Drums"/>
- <ChannelNameSetAssign Channel="11" NameSet="General MIDI Voices"/>
- <ChannelNameSetAssign Channel="12" NameSet="General MIDI Voices"/>
- <ChannelNameSetAssign Channel="13" NameSet="General MIDI Voices"/>
- <ChannelNameSetAssign Channel="14" NameSet="General MIDI Voices"/>
- <ChannelNameSetAssign Channel="15" NameSet="General MIDI Voices"/>
- <ChannelNameSetAssign Channel="16" NameSet="General MIDI Voices"/>
- </ChannelNameSetAssignments>
- </CustomDeviceMode>
- <ChannelNameSet Name="MIDI Voices">
- <AvailableForChannels>
- <AvailableChannel Channel="1" Available="true"/>
- <AvailableChannel Channel="2" Available="true"/>
- <AvailableChannel Channel="3" Available="true"/>
- <AvailableChannel Channel="4" Available="true"/>
- <AvailableChannel Channel="5" Available="true"/>
- <AvailableChannel Channel="6" Available="true"/>
- <AvailableChannel Channel="7" Available="true"/>
- <AvailableChannel Channel="8" Available="true"/>
- <AvailableChannel Channel="9" Available="true"/>
- <AvailableChannel Channel="10" Available="true"/>
- <AvailableChannel Channel="11" Available="true"/>
- <AvailableChannel Channel="12" Available="true"/>
- <AvailableChannel Channel="13" Available="true"/>
- <AvailableChannel Channel="14" Available="true"/>
- <AvailableChannel Channel="15" Available="true"/>
- <AvailableChannel Channel="16" Available="true"/>
- </AvailableForChannels>
- <UsesControlNameList Name="Controls"/>
- <PatchBank Name="Patches">
- <UsesPatchNameList Name="Unnamed Patches"/>
- </PatchBank>
- </ChannelNameSet>
- <ChannelNameSet Name="General MIDI Voices">
- <AvailableForChannels>
- <AvailableChannel Channel="1" Available="true"/>
- <AvailableChannel Channel="2" Available="true"/>
- <AvailableChannel Channel="3" Available="true"/>
- <AvailableChannel Channel="4" Available="true"/>
- <AvailableChannel Channel="5" Available="true"/>
- <AvailableChannel Channel="6" Available="true"/>
- <AvailableChannel Channel="7" Available="true"/>
- <AvailableChannel Channel="8" Available="true"/>
- <AvailableChannel Channel="9" Available="true"/>
- <AvailableChannel Channel="11" Available="true"/>
- <AvailableChannel Channel="12" Available="true"/>
- <AvailableChannel Channel="13" Available="true"/>
- <AvailableChannel Channel="14" Available="true"/>
- <AvailableChannel Channel="15" Available="true"/>
- <AvailableChannel Channel="16" Available="true"/>
- </AvailableForChannels>
- <UsesControlNameList Name="Controls"/>
- <PatchBank Name="Patches" ROM="false">
- <MIDICommands>
- <ControlChange Control="32" Value="0"/>
- </MIDICommands>
- <UsesPatchNameList Name="General MIDI Patches"/>
- </PatchBank>
- </ChannelNameSet>
- <ChannelNameSet Name="General MIDI Drums">
- <AvailableForChannels>
- <AvailableChannel Channel="10" Available="true"/>
- </AvailableForChannels>
- <UsesNoteNameList Name="General MIDI Drums"/>
- <PatchBank Name="Patches" ROM="false">
- <MIDICommands>
- <ControlChange Control="120" Value="120"/>
- <ControlChange Control="32" Value="0"/>
- </MIDICommands>
- <UsesPatchNameList Name="General MIDI Drum Patches"/>
- </PatchBank>
- </ChannelNameSet>
- <PatchNameList Name="Unnamed Patches">
- <Patch Number="1" Name="Patch 1" ProgramChange="0"/>
- <Patch Number="2" Name="Patch 2" ProgramChange="1"/>
- <Patch Number="3" Name="Patch 3" ProgramChange="2"/>
- <Patch Number="4" Name="Patch 4" ProgramChange="3"/>
- <Patch Number="5" Name="Patch 5" ProgramChange="4"/>
- <Patch Number="6" Name="Patch 6" ProgramChange="5"/>
- <Patch Number="7" Name="Patch 7" ProgramChange="6"/>
- <Patch Number="8" Name="Patch 8" ProgramChange="7"/>
- <Patch Number="9" Name="Patch 9" ProgramChange="8"/>
- <Patch Number="10" Name="Patch 10" ProgramChange="9"/>
- <Patch Number="11" Name="Patch 11" ProgramChange="10"/>
- <Patch Number="12" Name="Patch 12" ProgramChange="11"/>
- <Patch Number="13" Name="Patch 13" ProgramChange="12"/>
- <Patch Number="14" Name="Patch 14" ProgramChange="13"/>
- <Patch Number="15" Name="Patch 15" ProgramChange="14"/>
- <Patch Number="16" Name="Patch 16" ProgramChange="15"/>
- <Patch Number="17" Name="Patch 17" ProgramChange="16"/>
- <Patch Number="18" Name="Patch 18" ProgramChange="17"/>
- <Patch Number="19" Name="Patch 19" ProgramChange="18"/>
- <Patch Number="20" Name="Patch 20" ProgramChange="19"/>
- <Patch Number="21" Name="Patch 21" ProgramChange="20"/>
- <Patch Number="22" Name="Patch 22" ProgramChange="21"/>
- <Patch Number="23" Name="Patch 23" ProgramChange="22"/>
- <Patch Number="24" Name="Patch 24" ProgramChange="23"/>
- <Patch Number="25" Name="Patch 25" ProgramChange="24"/>
- <Patch Number="26" Name="Patch 26" ProgramChange="25"/>
- <Patch Number="27" Name="Patch 27" ProgramChange="26"/>
- <Patch Number="28" Name="Patch 28" ProgramChange="27"/>
- <Patch Number="29" Name="Patch 29" ProgramChange="28"/>
- <Patch Number="30" Name="Patch 30" ProgramChange="29"/>
- <Patch Number="31" Name="Patch 31" ProgramChange="30"/>
- <Patch Number="32" Name="Patch 32" ProgramChange="31"/>
- <Patch Number="33" Name="Patch 33" ProgramChange="32"/>
- <Patch Number="34" Name="Patch 34" ProgramChange="33"/>
- <Patch Number="35" Name="Patch 35" ProgramChange="34"/>
- <Patch Number="36" Name="Patch 36" ProgramChange="35"/>
- <Patch Number="37" Name="Patch 37" ProgramChange="36"/>
- <Patch Number="38" Name="Patch 38" ProgramChange="37"/>
- <Patch Number="39" Name="Patch 39" ProgramChange="38"/>
- <Patch Number="40" Name="Patch 40" ProgramChange="39"/>
- <Patch Number="41" Name="Patch 41" ProgramChange="40"/>
- <Patch Number="42" Name="Patch 42" ProgramChange="41"/>
- <Patch Number="43" Name="Patch 43" ProgramChange="42"/>
- <Patch Number="44" Name="Patch 44" ProgramChange="43"/>
- <Patch Number="45" Name="Patch 45" ProgramChange="44"/>
- <Patch Number="46" Name="Patch 46" ProgramChange="45"/>
- <Patch Number="47" Name="Patch 47" ProgramChange="46"/>
- <Patch Number="48" Name="Patch 48" ProgramChange="47"/>
- <Patch Number="49" Name="Patch 49" ProgramChange="48"/>
- <Patch Number="50" Name="Patch 50" ProgramChange="49"/>
- <Patch Number="51" Name="Patch 51" ProgramChange="50"/>
- <Patch Number="52" Name="Patch 52" ProgramChange="51"/>
- <Patch Number="53" Name="Patch 53" ProgramChange="52"/>
- <Patch Number="54" Name="Patch 54" ProgramChange="53"/>
- <Patch Number="55" Name="Patch 55" ProgramChange="54"/>
- <Patch Number="56" Name="Patch 56" ProgramChange="55"/>
- <Patch Number="57" Name="Patch 57" ProgramChange="56"/>
- <Patch Number="58" Name="Patch 58" ProgramChange="57"/>
- <Patch Number="59" Name="Patch 59" ProgramChange="58"/>
- <Patch Number="60" Name="Patch 60" ProgramChange="59"/>
- <Patch Number="61" Name="Patch 61" ProgramChange="60"/>
- <Patch Number="62" Name="Patch 62" ProgramChange="61"/>
- <Patch Number="63" Name="Patch 63" ProgramChange="62"/>
- <Patch Number="64" Name="Patch 64" ProgramChange="63"/>
- <Patch Number="65" Name="Patch 65" ProgramChange="64"/>
- <Patch Number="66" Name="Patch 66" ProgramChange="65"/>
- <Patch Number="67" Name="Patch 67" ProgramChange="66"/>
- <Patch Number="68" Name="Patch 68" ProgramChange="67"/>
- <Patch Number="69" Name="Patch 69" ProgramChange="68"/>
- <Patch Number="70" Name="Patch 70" ProgramChange="69"/>
- <Patch Number="71" Name="Patch 71" ProgramChange="70"/>
- <Patch Number="72" Name="Patch 72" ProgramChange="71"/>
- <Patch Number="73" Name="Patch 73" ProgramChange="72"/>
- <Patch Number="74" Name="Patch 74" ProgramChange="73"/>
- <Patch Number="75" Name="Patch 75" ProgramChange="74"/>
- <Patch Number="76" Name="Patch 76" ProgramChange="75"/>
- <Patch Number="77" Name="Patch 77" ProgramChange="76"/>
- <Patch Number="78" Name="Patch 78" ProgramChange="77"/>
- <Patch Number="79" Name="Patch 79" ProgramChange="78"/>
- <Patch Number="80" Name="Patch 80" ProgramChange="79"/>
- <Patch Number="81" Name="Patch 81" ProgramChange="80"/>
- <Patch Number="82" Name="Patch 82" ProgramChange="81"/>
- <Patch Number="83" Name="Patch 83" ProgramChange="82"/>
- <Patch Number="84" Name="Patch 84" ProgramChange="83"/>
- <Patch Number="85" Name="Patch 85" ProgramChange="84"/>
- <Patch Number="86" Name="Patch 86" ProgramChange="85"/>
- <Patch Number="87" Name="Patch 87" ProgramChange="86"/>
- <Patch Number="88" Name="Patch 88" ProgramChange="87"/>
- <Patch Number="89" Name="Patch 89" ProgramChange="88"/>
- <Patch Number="90" Name="Patch 90" ProgramChange="89"/>
- <Patch Number="91" Name="Patch 91" ProgramChange="90"/>
- <Patch Number="92" Name="Patch 92" ProgramChange="91"/>
- <Patch Number="93" Name="Patch 93" ProgramChange="92"/>
- <Patch Number="94" Name="Patch 94" ProgramChange="93"/>
- <Patch Number="95" Name="Patch 95" ProgramChange="94"/>
- <Patch Number="96" Name="Patch 96" ProgramChange="95"/>
- <Patch Number="97" Name="Patch 97" ProgramChange="96"/>
- <Patch Number="98" Name="Patch 98" ProgramChange="97"/>
- <Patch Number="99" Name="Patch 99" ProgramChange="98"/>
- <Patch Number="100" Name="Patch 100" ProgramChange="99"/>
- <Patch Number="101" Name="Patch 101" ProgramChange="100"/>
- <Patch Number="102" Name="Patch 102" ProgramChange="101"/>
- <Patch Number="103" Name="Patch 103" ProgramChange="102"/>
- <Patch Number="104" Name="Patch 104" ProgramChange="103"/>
- <Patch Number="105" Name="Patch 105" ProgramChange="104"/>
- <Patch Number="106" Name="Patch 106" ProgramChange="105"/>
- <Patch Number="107" Name="Patch 107" ProgramChange="106"/>
- <Patch Number="108" Name="Patch 108" ProgramChange="107"/>
- <Patch Number="109" Name="Patch 109" ProgramChange="108"/>
- <Patch Number="110" Name="Patch 110" ProgramChange="109"/>
- <Patch Number="111" Name="Patch 111" ProgramChange="110"/>
- <Patch Number="112" Name="Patch 112" ProgramChange="111"/>
- <Patch Number="113" Name="Patch 113" ProgramChange="112"/>
- <Patch Number="114" Name="Patch 114" ProgramChange="113"/>
- <Patch Number="115" Name="Patch 115" ProgramChange="114"/>
- <Patch Number="116" Name="Patch 116" ProgramChange="115"/>
- <Patch Number="117" Name="Patch 117" ProgramChange="116"/>
- <Patch Number="118" Name="Patch 118" ProgramChange="117"/>
- <Patch Number="119" Name="Patch 119" ProgramChange="118"/>
- <Patch Number="120" Name="Patch 120" ProgramChange="119"/>
- <Patch Number="121" Name="Patch 121" ProgramChange="120"/>
- <Patch Number="122" Name="Patch 122" ProgramChange="121"/>
- <Patch Number="123" Name="Patch 123" ProgramChange="122"/>
- <Patch Number="124" Name="Patch 124" ProgramChange="123"/>
- <Patch Number="125" Name="Patch 125" ProgramChange="124"/>
- <Patch Number="126" Name="Patch 126" ProgramChange="125"/>
- <Patch Number="127" Name="Patch 127" ProgramChange="126"/>
- <Patch Number="128" Name="Patch 128" ProgramChange="127"/>
- </PatchNameList>
- <PatchNameList Name="General MIDI Patches">
- <Patch Number="0" Name="Acoustic Grand Piano" ProgramChange="0"/>
- <Patch Number="1" Name="Bright Acoustic Piano" ProgramChange="1"/>
- <Patch Number="2" Name="Electric Grand Piano" ProgramChange="2"/>
- <Patch Number="3" Name="Honky-tonk Piano" ProgramChange="3"/>
- <Patch Number="4" Name="Rhodes Piano" ProgramChange="4"/>
- <Patch Number="5" Name="Chorused Piano" ProgramChange="5"/>
- <Patch Number="6" Name="Harpsichord" ProgramChange="6"/>
- <Patch Number="7" Name="Clavinet" ProgramChange="7"/>
- <Patch Number="8" Name="Celesta" ProgramChange="8"/>
- <Patch Number="9" Name="Glockenspiel" ProgramChange="9"/>
- <Patch Number="10" Name="Music Box" ProgramChange="10"/>
- <Patch Number="11" Name="Vibraphone" ProgramChange="11"/>
- <Patch Number="12" Name="Marimba" ProgramChange="12"/>
- <Patch Number="13" Name="Xylophone" ProgramChange="13"/>
- <Patch Number="14" Name="Tubular Bells" ProgramChange="14"/>
- <Patch Number="15" Name="Dulcimer" ProgramChange="15"/>
- <Patch Number="16" Name="Hammond Organ" ProgramChange="16"/>
- <Patch Number="17" Name="Percussive Organ" ProgramChange="17"/>
- <Patch Number="18" Name="Rock Organ" ProgramChange="18"/>
- <Patch Number="19" Name="Church Organ" ProgramChange="19"/>
- <Patch Number="20" Name="Reed Organ" ProgramChange="20"/>
- <Patch Number="21" Name="Accordion" ProgramChange="21"/>
- <Patch Number="22" Name="Harmonica" ProgramChange="22"/>
- <Patch Number="23" Name="Tango Accordion" ProgramChange="23"/>
- <Patch Number="24" Name="Acoustic Guitar (nylon)" ProgramChange="24"/>
- <Patch Number="25" Name="Acoustic Guitar (steel)" ProgramChange="25"/>
- <Patch Number="26" Name="Electric Guitar (jazz)" ProgramChange="26"/>
- <Patch Number="27" Name="Electric Guitar (clean)" ProgramChange="27"/>
- <Patch Number="28" Name="Electric Guitar (muted)" ProgramChange="28"/>
- <Patch Number="29" Name="Overdriven Guitar" ProgramChange="29"/>
- <Patch Number="30" Name="Distortion Guitar" ProgramChange="30"/>
- <Patch Number="31" Name="Guitar Harmonics" ProgramChange="31"/>
- <Patch Number="32" Name="Acoustic Bass" ProgramChange="32"/>
- <Patch Number="33" Name="Electric Bass (finger)" ProgramChange="33"/>
- <Patch Number="34" Name="Electric Bass (pick)" ProgramChange="34"/>
- <Patch Number="35" Name="Fretless Bass" ProgramChange="35"/>
- <Patch Number="36" Name="Slap Bass 1" ProgramChange="36"/>
- <Patch Number="37" Name="Slap Bass 2" ProgramChange="37"/>
- <Patch Number="38" Name="Synth Bass 1" ProgramChange="38"/>
- <Patch Number="39" Name="Synth Bass 2" ProgramChange="39"/>
- <Patch Number="40" Name="Violin" ProgramChange="40"/>
- <Patch Number="41" Name="Viola" ProgramChange="41"/>
- <Patch Number="42" Name="Cello" ProgramChange="42"/>
- <Patch Number="43" Name="Contrabass" ProgramChange="43"/>
- <Patch Number="44" Name="Tremolo Strings" ProgramChange="44"/>
- <Patch Number="45" Name="Pizzicato Strings" ProgramChange="45"/>
- <Patch Number="46" Name="Orchestral Harp" ProgramChange="46"/>
- <Patch Number="47" Name="Timpani" ProgramChange="47"/>
- <Patch Number="48" Name="String Ensemble 1" ProgramChange="48"/>
- <Patch Number="49" Name="String Ensemble 2" ProgramChange="49"/>
- <Patch Number="50" Name="SynthStrings 1" ProgramChange="50"/>
- <Patch Number="51" Name="SynthStrings 2" ProgramChange="51"/>
- <Patch Number="52" Name="Choir Aahs" ProgramChange="52"/>
- <Patch Number="53" Name="Voice Oohs" ProgramChange="53"/>
- <Patch Number="54" Name="Synth Voice" ProgramChange="54"/>
- <Patch Number="55" Name="Orchestra Hit" ProgramChange="55"/>
- <Patch Number="56" Name="Trumpet" ProgramChange="56"/>
- <Patch Number="57" Name="Trombone" ProgramChange="57"/>
- <Patch Number="58" Name="Tuba" ProgramChange="58"/>
- <Patch Number="59" Name="Muted Trumpet" ProgramChange="59"/>
- <Patch Number="60" Name="French Horn" ProgramChange="60"/>
- <Patch Number="61" Name="Brass Section" ProgramChange="61"/>
- <Patch Number="62" Name="Synth Brass 1" ProgramChange="62"/>
- <Patch Number="63" Name="Synth Brass 2" ProgramChange="63"/>
- <Patch Number="64" Name="Soprano Sax" ProgramChange="64"/>
- <Patch Number="65" Name="Alto Sax" ProgramChange="65"/>
- <Patch Number="66" Name="Tenor Sax" ProgramChange="66"/>
- <Patch Number="67" Name="Baritone Sax" ProgramChange="67"/>
- <Patch Number="68" Name="Oboe" ProgramChange="68"/>
- <Patch Number="69" Name="English Horn" ProgramChange="69"/>
- <Patch Number="70" Name="Bassoon" ProgramChange="70"/>
- <Patch Number="71" Name="Clarinet" ProgramChange="71"/>
- <Patch Number="72" Name="Piccolo" ProgramChange="72"/>
- <Patch Number="73" Name="Flute" ProgramChange="73"/>
- <Patch Number="74" Name="Recorder" ProgramChange="74"/>
- <Patch Number="75" Name="Pan Flute" ProgramChange="75"/>
- <Patch Number="76" Name="Bottle Blow" ProgramChange="76"/>
- <Patch Number="77" Name="Shakuhachi" ProgramChange="77"/>
- <Patch Number="78" Name="Whistle" ProgramChange="78"/>
- <Patch Number="79" Name="Ocarina" ProgramChange="79"/>
- <Patch Number="80" Name="Lead 1 (square)" ProgramChange="80"/>
- <Patch Number="81" Name="Lead 2 (sawtooth)" ProgramChange="81"/>
- <Patch Number="82" Name="Lead 3 (calliope lead)" ProgramChange="82"/>
- <Patch Number="83" Name="Lead 4 (chiff lead)" ProgramChange="83"/>
- <Patch Number="84" Name="Lead 5 (charang)" ProgramChange="84"/>
- <Patch Number="85" Name="Lead 6 (voice)" ProgramChange="85"/>
- <Patch Number="86" Name="Lead 7 (fifths)" ProgramChange="86"/>
- <Patch Number="87" Name="Lead 8 (bass + lead)" ProgramChange="87"/>
- <Patch Number="88" Name="Pad 1 (new age)" ProgramChange="88"/>
- <Patch Number="89" Name="Pad 2 (warm)" ProgramChange="89"/>
- <Patch Number="90" Name="Pad 3 (polysynth)" ProgramChange="90"/>
- <Patch Number="91" Name="Pad 4 (choir)" ProgramChange="91"/>
- <Patch Number="92" Name="Pad 5 (bowed)" ProgramChange="92"/>
- <Patch Number="93" Name="Pad 6 (metallic)" ProgramChange="93"/>
- <Patch Number="94" Name="Pad 7 (halo)" ProgramChange="94"/>
- <Patch Number="95" Name="Pad 8 (sweep)" ProgramChange="95"/>
- <Patch Number="96" Name="FX 1 (rain)" ProgramChange="96"/>
- <Patch Number="97" Name="FX 2 (soundtrack)" ProgramChange="97"/>
- <Patch Number="98" Name="FX 3 (crystal)" ProgramChange="98"/>
- <Patch Number="99" Name="FX 4 (atmosphere)" ProgramChange="99"/>
- <Patch Number="100" Name="FX 5 (brightness)" ProgramChange="100"/>
- <Patch Number="101" Name="FX 6 (goblins)" ProgramChange="101"/>
- <Patch Number="102" Name="FX 7 (echoes)" ProgramChange="102"/>
- <Patch Number="103" Name="FX 8 (sci-fi)" ProgramChange="103"/>
- <Patch Number="104" Name="Sitar" ProgramChange="104"/>
- <Patch Number="105" Name="Banjo" ProgramChange="105"/>
- <Patch Number="106" Name="Shamisen" ProgramChange="106"/>
- <Patch Number="107" Name="Koto" ProgramChange="107"/>
- <Patch Number="108" Name="Kalimba" ProgramChange="108"/>
- <Patch Number="109" Name="Bagpipe" ProgramChange="109"/>
- <Patch Number="110" Name="Fiddle" ProgramChange="110"/>
- <Patch Number="111" Name="Shanai" ProgramChange="111"/>
- <Patch Number="112" Name="Tinkle Bell" ProgramChange="112"/>
- <Patch Number="113" Name="Agogo" ProgramChange="113"/>
- <Patch Number="114" Name="Steel Drums" ProgramChange="114"/>
- <Patch Number="115" Name="Woodblock" ProgramChange="115"/>
- <Patch Number="116" Name="Taiko Drum" ProgramChange="116"/>
- <Patch Number="117" Name="Melodic Tom" ProgramChange="117"/>
- <Patch Number="118" Name="Synth Drum" ProgramChange="118"/>
- <Patch Number="119" Name="Reverse Cymbal" ProgramChange="119"/>
- <Patch Number="120" Name="Guitar Fret Noise" ProgramChange="120"/>
- <Patch Number="121" Name="Breath Noise" ProgramChange="121"/>
- <Patch Number="122" Name="Seashore" ProgramChange="122"/>
- <Patch Number="123" Name="Bird Tweet" ProgramChange="123"/>
- <Patch Number="124" Name="Telephone Ring" ProgramChange="124"/>
- <Patch Number="125" Name="Helicopter" ProgramChange="125"/>
- <Patch Number="126" Name="Applause" ProgramChange="126"/>
- <Patch Number="127" Name="Gunshot" ProgramChange="127"/>
- </PatchNameList>
- <PatchNameList Name="General MIDI Drum Patches">
- <Patch Number="1" Name="Standard Kit" ProgramChange="1"/>
- <Patch Number="9" Name="Room Kit" ProgramChange="9"/>
- <Patch Number="17" Name="Power Kit" ProgramChange="17"/>
- <Patch Number="25" Name="Electronic Kit" ProgramChange="25"/>
- <Patch Number="26" Name="TR-808 Kit" ProgramChange="26"/>
- <Patch Number="33" Name="Jazz Kit" ProgramChange="33"/>
- <Patch Number="41" Name="Brush Kit" ProgramChange="41"/>
- <Patch Number="49" Name="Orchestra Kit" ProgramChange="49"/>
- <Patch Number="57" Name="Sound FX Kit" ProgramChange="57"/>
- <Patch Number="128" Name="CM-64/CM-32L" ProgramChange="128"/>
- </PatchNameList>
- <ControlNameList Name="Controls">
- <Control Type="7bit" Number="0" Name="Bank Select"/>
- <Control Type="7bit" Number="1" Name="Modulation Wheel or Lever"/>
- <Control Type="7bit" Number="2" Name="Breath Controller"/>
- <Control Type="7bit" Number="3" Name="Undefined"/>
- <Control Type="7bit" Number="4" Name="Foot Controller"/>
- <Control Type="7bit" Number="5" Name="Portamento Time"/>
- <Control Type="7bit" Number="6" Name="Data Entry MSB"/>
- <Control Type="7bit" Number="7" Name="Channel Volume"/>
- <Control Type="7bit" Number="8" Name="Balance"/>
- <Control Type="7bit" Number="9" Name="Undefined"/>
- <Control Type="7bit" Number="10" Name="Pan"/>
- <Control Type="7bit" Number="11" Name="Expression Controller"/>
- <Control Type="7bit" Number="12" Name="Effect Control 1"/>
- <Control Type="7bit" Number="13" Name="Effect Control 2"/>
- <Control Type="7bit" Number="14" Name="Undefined"/>
- <Control Type="7bit" Number="15" Name="Undefined"/>
- <Control Type="7bit" Number="16" Name="General Purpose Controller 1"/>
- <Control Type="7bit" Number="17" Name="General Purpose Controller 2"/>
- <Control Type="7bit" Number="18" Name="General Purpose Controller 3"/>
- <Control Type="7bit" Number="19" Name="General Purpose Controller 4"/>
- <Control Type="7bit" Number="20" Name="Undefined"/>
- <Control Type="7bit" Number="21" Name="Undefined"/>
- <Control Type="7bit" Number="22" Name="Undefined"/>
- <Control Type="7bit" Number="23" Name="Undefined"/>
- <Control Type="7bit" Number="24" Name="Undefined"/>
- <Control Type="7bit" Number="25" Name="Undefined"/>
- <Control Type="7bit" Number="26" Name="Undefined"/>
- <Control Type="7bit" Number="27" Name="Undefined"/>
- <Control Type="7bit" Number="28" Name="Undefined"/>
- <Control Type="7bit" Number="29" Name="Undefined"/>
- <Control Type="7bit" Number="30" Name="Undefined"/>
- <Control Type="7bit" Number="31" Name="Undefined"/>
- <Control Type="7bit" Number="32" Name="LSB for Control 0 (Bank Select) (Fine)"/>
- <Control Type="7bit" Number="33" Name="LSB for Control 1 (Modulation Wheel or Lever) (Fine)"/>
- <Control Type="7bit" Number="34" Name="LSB for Control 2 (Breath Controller) (Fine)"/>
- <Control Type="7bit" Number="35" Name="LSB for Control 3 (Undefined) (Fine)"/>
- <Control Type="7bit" Number="36" Name="LSB for Control 4 (Foot Controller) (Fine)"/>
- <Control Type="7bit" Number="37" Name="LSB for Control 5 (Portamento Time) (Fine)"/>
- <Control Type="7bit" Number="38" Name="LSB for Control 6 (Data Entry) (Fine)"/>
- <Control Type="7bit" Number="39" Name="LSB for Control 7 (Channel Volume) (Fine)"/>
- <Control Type="7bit" Number="40" Name="LSB for Control 8 (Balance) (Fine)"/>
- <Control Type="7bit" Number="41" Name="LSB for Control 9 (Undefined) (Fine)"/>
- <Control Type="7bit" Number="42" Name="LSB for Control 10 (Pan) (Fine)"/>
- <Control Type="7bit" Number="43" Name="LSB for Control 11 (Expression Controller) (Fine)"/>
- <Control Type="7bit" Number="44" Name="LSB for Control 12 (Effect control 1) (Fine)"/>
- <Control Type="7bit" Number="45" Name="LSB for Control 13 (Effect control 2) (Fine)"/>
- <Control Type="7bit" Number="46" Name="LSB for Control 14 (Undefined) (Fine)"/>
- <Control Type="7bit" Number="47" Name="LSB for Control 15 (Undefined) (Fine)"/>
- <Control Type="7bit" Number="48" Name="LSB for Control 16 (General Purpose Controller 1) (Fine)"/>
- <Control Type="7bit" Number="49" Name="LSB for Control 17 (General Purpose Controller 2) (Fine)"/>
- <Control Type="7bit" Number="50" Name="LSB for Control 18 (General Purpose Controller 3) (Fine)"/>
- <Control Type="7bit" Number="51" Name="LSB for Control 19 (General Purpose Controller 4) (Fine)"/>
- <Control Type="7bit" Number="52" Name="LSB for Control 20 (Undefined) (Fine)"/>
- <Control Type="7bit" Number="53" Name="LSB for Control 21 (Undefined) (Fine)"/>
- <Control Type="7bit" Number="54" Name="LSB for Control 22 (Undefined) (Fine)"/>
- <Control Type="7bit" Number="55" Name="LSB for Control 23 (Undefined) (Fine)"/>
- <Control Type="7bit" Number="56" Name="LSB for Control 24 (Undefined) (Fine)"/>
- <Control Type="7bit" Number="57" Name="LSB for Control 25 (Undefined) (Fine)"/>
- <Control Type="7bit" Number="58" Name="LSB for Control 26 (Undefined) (Fine)"/>
- <Control Type="7bit" Number="59" Name="LSB for Control 27 (Undefined) (Fine)"/>
- <Control Type="7bit" Number="60" Name="LSB for Control 28 (Undefined) (Fine)"/>
- <Control Type="7bit" Number="61" Name="LSB for Control 29 (Undefined) (Fine)"/>
- <Control Type="7bit" Number="62" Name="LSB for Control 30 (Undefined) (Fine)"/>
- <Control Type="7bit" Number="63" Name="LSB for Control 31 (Undefined) (Fine)"/>
- <Control Type="7bit" Number="64" Name="Damper Pedal on/off (Sustain) ≤63 off, ≥64 on"/>
- <Control Type="7bit" Number="65" Name="Portamento On/Off ≤63 off, ≥64 on"/>
- <Control Type="7bit" Number="66" Name="Sostenuto On/Off ≤63 off, ≥64 on"/>
- <Control Type="7bit" Number="67" Name="Soft Pedal On/Off ≤63 off, ≥64 on"/>
- <Control Type="7bit" Number="68" Name="Legato Footswitch ≤63 Normal, ≥64 Legato"/>
- <Control Type="7bit" Number="69" Name="Hold 2 ≤63 off, ≥64 on"/>
- <Control Type="7bit" Number="70" Name="Sound Controller 1 (default: Sound Variation) (Fine)"/>
- <Control Type="7bit" Number="71" Name="Sound Controller 2 (default: Timbre/Harmonic Intens.) (Fine)"/>
- <Control Type="7bit" Number="72" Name="Sound Controller 3 (default: Release Time) (Fine)"/>
- <Control Type="7bit" Number="73" Name="Sound Controller 4 (default: Attack Time) (Fine)"/>
- <Control Type="7bit" Number="74" Name="Sound Controller 5 (default: Brightness) (Fine)"/>
- <Control Type="7bit" Number="75" Name="Sound Controller 6 (default: Decay Time) (Fine)"/>
- <Control Type="7bit" Number="76" Name="Sound Controller 7 (default: Vibrato Rate) (Fine)"/>
- <Control Type="7bit" Number="77" Name="Sound Controller 8 (default: Vibrato Depth) (Fine)"/>
- <Control Type="7bit" Number="78" Name="Sound Controller 9 (default: Vibrato Delay) (Fine)"/>
- <Control Type="7bit" Number="79" Name="Sound Controller 10 (default undefined) (Fine)"/>
- <Control Type="7bit" Number="80" Name="General Purpose Controller 5 (Fine)"/>
- <Control Type="7bit" Number="81" Name="General Purpose Controller 6 (Fine)"/>
- <Control Type="7bit" Number="82" Name="General Purpose Controller 7 (Fine)"/>
- <Control Type="7bit" Number="83" Name="General Purpose Controller 8 (Fine)"/>
- <Control Type="7bit" Number="84" Name="Portamento Control (Fine)"/>
- <Control Type="7bit" Number="85" Name="(Undefined)"/>
- <Control Type="7bit" Number="86" Name="(Undefined)"/>
- <Control Type="7bit" Number="87" Name="(Undefined)"/>
- <Control Type="7bit" Number="88" Name="High Resolution Velocity Prefix (Velocity LSB)"/>
- <Control Type="7bit" Number="89" Name="(Undefined)"/>
- <Control Type="7bit" Number="90" Name="(Undefined)"/>
- <Control Type="7bit" Number="91" Name="Effects 1 Depth (default: Reverb Send Level)"/>
- <Control Type="7bit" Number="92" Name="Effects 2 Depth"/>
- <Control Type="7bit" Number="93" Name="Effects 3 Depth (default: Chorus Send Level)"/>
- <Control Type="7bit" Number="94" Name="Effects 4 Depth"/>
- <Control Type="7bit" Number="95" Name="Effects 5 Depth"/>
- <Control Type="7bit" Number="96" Name="Data Increment (Data Entry +1)"/>
- <Control Type="7bit" Number="97" Name="Data Decrement (Data Entry -1)"/>
- <Control Type="7bit" Number="98" Name="Non-Registered Parameter Number LSB"/>
- <Control Type="7bit" Number="99" Name="Non-Registered Parameter Number MSB"/>
- <Control Type="7bit" Number="100" Name="Registered Parameter Number LSB"/>
- <Control Type="7bit" Number="101" Name="Registered Parameter Number MSB"/>
- <Control Type="7bit" Number="102" Name="(Undefined)"/>
- <Control Type="7bit" Number="103" Name="(Undefined)"/>
- <Control Type="7bit" Number="104" Name="(Undefined)"/>
- <Control Type="7bit" Number="105" Name="(Undefined)"/>
- <Control Type="7bit" Number="106" Name="(Undefined)"/>
- <Control Type="7bit" Number="107" Name="(Undefined)"/>
- <Control Type="7bit" Number="108" Name="(Undefined)"/>
- <Control Type="7bit" Number="109" Name="(Undefined)"/>
- <Control Type="7bit" Number="110" Name="(Undefined)"/>
- <Control Type="7bit" Number="111" Name="(Undefined)"/>
- <Control Type="7bit" Number="112" Name="(Undefined)"/>
- <Control Type="7bit" Number="113" Name="(Undefined)"/>
- <Control Type="7bit" Number="114" Name="(Undefined)"/>
- <Control Type="7bit" Number="115" Name="(Undefined)"/>
- <Control Type="7bit" Number="116" Name="(Undefined)"/>
- <Control Type="7bit" Number="117" Name="(Undefined)"/>
- <Control Type="7bit" Number="118" Name="(Undefined)"/>
- <Control Type="7bit" Number="119" Name="(Undefined)"/>
- <Control Type="7bit" Number="120" Name="[Channel Mode Message] All Sound Off"/>
- <Control Type="7bit" Number="121" Name="[Channel Mode Message] Reset All Controllers"/>
- <Control Type="7bit" Number="122" Name="[Channel Mode Message] Local Control On/Off 0 off, 127 on"/>
- <Control Type="7bit" Number="123" Name="[Channel Mode Message] All Notes Off"/>
- <Control Type="7bit" Number="124" Name="[Channel Mode Message] Omni Mode Off (+ all notes off)"/>
- <Control Type="7bit" Number="125" Name="[Channel Mode Message] Omni Mode On (+ all notes off)"/>
- <Control Type="7bit" Number="126" Name="[Channel Mode Message] Mono Mode On (+ poly off, + all notes off)"/>
- <Control Type="7bit" Number="127" Name="[Channel Mode Message] Poly Mode On (+ mono off, +all notes off) 0"/>
- </ControlNameList>
- <NoteNameList Name="General MIDI Drums">
- <Note Number="35" Name="Bass Drum 2"/>
- <Note Number="36" Name="Bass Drum 1"/>
- <Note Number="37" Name="Side Stick/Rimshot"/>
- <Note Number="38" Name="Snare Drum 1"/>
- <Note Number="39" Name="Hand Clap"/>
- <Note Number="40" Name="Snare Drum 2"/>
- <Note Number="41" Name="Low Tom 2"/>
- <Note Number="42" Name="Closed Hi-hat"/>
- <Note Number="43" Name="Low Tom 1"/>
- <Note Number="44" Name="Pedal Hi-hat"/>
- <Note Number="45" Name="Mid Tom 2"/>
- <Note Number="46" Name="Open Hi-hat"/>
- <Note Number="47" Name="Mid Tom 1"/>
- <Note Number="48" Name="High Tom 2"/>
- <Note Number="49" Name="Crash Cymbal 1"/>
- <Note Number="50" Name="High Tom 1"/>
- <Note Number="51" Name="Ride Cymbal 1"/>
- <Note Number="52" Name="Chinese Cymbal"/>
- <Note Number="53" Name="Ride Bell"/>
- <Note Number="54" Name="Tambourine"/>
- <Note Number="55" Name="Splash Cymbal"/>
- <Note Number="56" Name="Cowbell"/>
- <Note Number="57" Name="Crash Cymbal 2"/>
- <Note Number="58" Name="Vibra Slap"/>
- <Note Number="59" Name="Ride Cymbal 2"/>
- <Note Number="60" Name="High Bongo"/>
- <Note Number="61" Name="Low Bongo"/>
- <Note Number="62" Name="Mute High Conga"/>
- <Note Number="63" Name="Open High Conga"/>
- <Note Number="64" Name="Low Conga"/>
- <Note Number="65" Name="High Timbale"/>
- <Note Number="66" Name="Low Timbale"/>
- <Note Number="67" Name="High Agogô"/>
- <Note Number="68" Name="Low Agogô"/>
- <Note Number="69" Name="Cabasa"/>
- <Note Number="70" Name="Maracas"/>
- <Note Number="71" Name="Short Whistle"/>
- <Note Number="72" Name="Long Whistle"/>
- <Note Number="73" Name="Short Güiro"/>
- <Note Number="74" Name="Long Güiro"/>
- <Note Number="75" Name="Claves"/>
- <Note Number="76" Name="High Wood Block"/>
- <Note Number="77" Name="Low Wood Block"/>
- <Note Number="78" Name="Mute Cuíca"/>
- <Note Number="79" Name="Open Cuíca"/>
- <Note Number="80" Name="Mute Triangle"/>
- <Note Number="81" Name="Open Triangle"/>
- </NoteNameList>
- </MasterDeviceNames>
-</MIDINameDocument>
diff --git a/data/osx/Info.plist.in b/data/osx/Info.plist.in
deleted file mode 100644
index cb697de..0000000
--- a/data/osx/Info.plist.in
+++ /dev/null
@@ -1,62 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
-<plist version="1.0">
-<dict>
- <key>CFBundleDevelopmentRegion</key>
- <string>English</string>
- <key>CFBundleDocumentTypes</key>
- <array>
- <dict>
- <key>CFBundleTypeExtensions</key>
- <array>
- <string>zrythm</string>
- </array>
- <key>CFBundleTypeOSTypes</key>
- <array>
- <string>****</string>
- <string>fold</string>
- </array>
- <key>CFBundleTypeRole</key>
- <string>Editor</string>
- <key>CFBundleTypeIconFile</key>
- <string>zrythm.icns</string>
- </dict>
- </array>
- <key>CFBundleExecutable</key>
- <string>zrythm</string>
- <key>CFBundleGetInfoString</key>
- <string>@PACKAGE_VERSION@, (C) 2018-2019 Alexandros Theodotou https://www.zrythm.org</string>
- <key>CFBundleIconFile</key>
- <string>zrythm.icns</string>
- <key>CFBundleIdentifier</key>
- <string>org.zrythm.Zrythm</string>
- <key>CFBundleInfoDictionaryVersion</key>
- <string>6.0</string>
- <key>CFBundleName</key>
- <string>Zrythm</string>
- <key>CFBundleDisplayName</key>
- <string>Zrythm</string>
- <key>CFBundlePackageType</key>
- <string>APPL</string>
- <key>CFBundleShortVersions</key>
- <string>@PACKAGE_VERSION@</string>
- <key>CFBundleSignature</key>
- <string>????</string>
- <key>CFBundleVersion</key>
- <string>@PACKAGE_VERSION@</string>
- <key>LSUIElement</key>
- <string>0</string>
- <key>NSMainNibFile</key>
- <string>MainMenu</string>
- <key>NSPrincipalClass</key>
- <string>NSApplication</string>
- <key>NSHumanReadableCopyright</key>
- <string>Copyright 2018 - 2019 Alexandros Theodotou, GNU General Public LIcense.</string>
- <key>LSMinimumSystemVersion</key>
- <string>10.4</string>
- <key>GtkOSXLaunchScriptFile</key>
- <string>gtk3-launcher.sh</string>
- <key>NSHighResolutionCapable</key>
- <true/>
-</dict>
-</plist>
diff --git a/data/osx/appdmg.json b/data/osx/appdmg.json
deleted file mode 100644
index e59d2d8..0000000
--- a/data/osx/appdmg.json
+++ /dev/null
@@ -1,8 +0,0 @@
-{
- "title": "Zrythm",
- "icon": "zrythm.icns",
- "contents": [
- { "x": 448, "y": 344, "type": "link", "path": "/Applications" },
- { "x": 192, "y": 344, "type": "file", "path": "../../build/osx/Zrythm.app" }
- ]
-}
diff --git a/data/osx/gtk3-launcher.sh b/data/osx/gtk3-launcher.sh
deleted file mode 100755
index 4e45767..0000000
--- a/data/osx/gtk3-launcher.sh
+++ /dev/null
@@ -1,172 +0,0 @@
-#!/bin/sh
-
-if test "x$GTK_DEBUG_LAUNCHER" != x; then
- set -x
-fi
-
-if test "x$GTK_DEBUG_GDB" != x; then
- EXEC="gdb --args"
-else
- EXEC=exec
-fi
-
-name=`basename "$0"`
-tmp="$0"
-tmp=`dirname "$tmp"`
-tmp=`dirname "$tmp"`
-bundle=`dirname "$tmp"`
-bundle_contents="$bundle"/Contents
-bundle_res="$bundle_contents"/Resources
-bundle_lib="$bundle_res"/lib
-bundle_bin="$bundle_res"/bin
-bundle_data="$bundle_res"/share
-bundle_etc="$bundle_res"/etc
-
-export XDG_CONFIG_DIRS="$bundle_etc"/xdg
-export XDG_DATA_DIRS="$bundle_data"
-export GTK_DATA_PREFIX="$bundle_res"
-export GTK_EXE_PREFIX="$bundle_res"
-export GTK_PATH="$bundle_res"
-
-# PANGO_* is no longer needed for pango >= 1.38
-export PANGO_RC_FILE="$bundle_etc/pango/pangorc"
-export PANGO_SYSCONFDIR="$bundle_etc"
-export PANGO_LIBDIR="$bundle_lib"
-
-export GDK_PIXBUF_MODULE_FILE="$bundle_lib/gdk-pixbuf-2.0/2.10.0/loaders.cache"
-if [ `uname -r | cut -d . -f 1` -ge 10 ]; then
- export GTK_IM_MODULE_FILE="$bundle_etc/gtk-3.0/gtk.immodules"
-fi
-
-APP=$name
-I18NDIR="$bundle_data/locale"
-# Set the locale-related variables appropriately:
-unset LANG LC_MESSAGES LC_MONETARY LC_COLLATE
-
-# Has a language ordering been set?
-# If so, set LC_MESSAGES and LANG accordingly; otherwise skip it.
-# First step uses sed to clean off the quotes and commas, to change - to _, and change the names for the chinese scripts from "Hans" to CN and "Hant" to TW.
-APPLELANGUAGES=`defaults read .GlobalPreferences AppleLanguages | sed -En -e 's/\-/_/' -e 's/Hant/TW/' -e 's/Hans/CN/' -e 's/[[:space:]]*\"?([[:alnum:]_]+)\"?,?/\1/p' `
-if test "$APPLELANGUAGES"; then
- # A language ordering exists.
- # Test, item per item, to see whether there is an corresponding locale.
- for L in $APPLELANGUAGES; do
- #test for exact matches:
- if test -f "$I18NDIR/${L}/LC_MESSAGES/$APP.mo"; then
- export LANG=$L
- break
- fi
- #This is a special case, because often the original strings are in US
- #English and there is no translation file.
- if test "x$L" == "xen_US"; then
- export LANG=$L
- break
- fi
- #OK, now test for just the first two letters:
- if test -f "$I18NDIR/${L:0:2}/LC_MESSAGES/$APP.mo"; then
- export LANG=${L:0:2}
- break
- fi
- #Same thing, but checking for any english variant.
- if test "x${L:0:2}" == "xen"; then
- export LANG=$L
- break
- fi;
- done
-fi
-unset APPLELANGUAGES L
-
-# If we didn't get a language from the language list, try the Collation preference, in case it's the only setting that exists.
-APPLECOLLATION=`defaults read .GlobalPreferences AppleCollationOrder`
-if test -z ${LANG} -a -n $APPLECOLLATION; then
- if test -f "$I18NDIR/${APPLECOLLATION:0:2}/LC_MESSAGES/$APP.mo"; then
- export LANG=${APPLECOLLATION:0:2}
- fi
-fi
-if test ! -z $APPLECOLLATION; then
- export LC_COLLATE=$APPLECOLLATION
-fi
-unset APPLECOLLATION
-
-# Continue by attempting to find the Locale preference.
-APPLELOCALE=`defaults read .GlobalPreferences AppleLocale`
-
-if test -f "$I18NDIR/${APPLELOCALE:0:5}/LC_MESSAGES/$APP.mo"; then
- if test -z $LANG; then
- export LANG="${APPLELOCALE:0:5}"
- fi
-
-elif test -z $LANG -a -f "$I18NDIR/${APPLELOCALE:0:2}/LC_MESSAGES/$APP.mo"; then
- export LANG="${APPLELOCALE:0:2}"
-fi
-
-#Next we need to set LC_MESSAGES. If at all possilbe, we want a full
-#5-character locale to avoid the "Locale not supported by C library"
-#warning from Gtk -- even though Gtk will translate with a
-#two-character code.
-if test -n $LANG; then
-#If the language code matches the applelocale, then that's the message
-#locale; otherwise, if it's longer than two characters, then it's
-#probably a good message locale and we'll go with it.
- if test $LANG == ${APPLELOCALE:0:5} -o $LANG != ${LANG:0:2}; then
- export LC_MESSAGES=$LANG
-#Next try if the Applelocale is longer than 2 chars and the language
-#bit matches $LANG
- elif test $LANG == ${APPLELOCALE:0:2} -a $APPLELOCALE > ${APPLELOCALE:0:2}; then
- export LC_MESSAGES=${APPLELOCALE:0:5}
-#Fail. Get a list of the locales in $PREFIX/share/locale that match
-#our two letter language code and pick the first one, special casing
-#english to set en_US
- elif test $LANG == "en"; then
- export LC_MESSAGES="en_US"
- else
- LOC=`find $PREFIX/share/locale -name $LANG???`
- for L in $LOC; do
- export LC_MESSAGES=$L
- done
- fi
-else
-#All efforts have failed, so default to US english
- export LANG="en_US"
- export LC_MESSAGES="en_US"
-fi
-CURRENCY=`echo $APPLELOCALE | sed -En 's/.*currency=([[:alpha:]]+).*/\1/p'`
-if test "x$CURRENCY" != "x"; then
-#The user has set a special currency. Gtk doesn't install LC_MONETARY files, but Apple does in /usr/share/locale, so we're going to look there for a locale to set LC_CURRENCY to.
- if test -f /usr/local/share/$LC_MESSAGES/LC_MONETARY; then
- if test -a `cat /usr/local/share/$LC_MESSAGES/LC_MONETARY` == $CURRENCY; then
- export LC_MONETARY=$LC_MESSAGES
- fi
- fi
- if test -z "$LC_MONETARY"; then
- FILES=`find /usr/share/locale -name LC_MONETARY -exec grep -H $CURRENCY {} \;`
- if test -n "$FILES"; then
- export LC_MONETARY=`echo $FILES | sed -En 's%/usr/share/locale/([[:alpha:]_]+)/LC_MONETARY.*%\1%p'`
- fi
- fi
-fi
-#No currency value means that the AppleLocale governs:
-if test -z "$LC_MONETARY"; then
- LC_MONETARY=${APPLELOCALE:0:5}
-fi
-#For Gtk, which only looks at LC_ALL:
-export LC_ALL=$LC_MESSAGES
-
-unset APPLELOCALE FILES LOC
-
-if test -f "$bundle_lib/charset.alias"; then
- export CHARSETALIASDIR="$bundle_lib"
-fi
-
-# Extra arguments can be added in environment.sh.
-EXTRA_ARGS=
-if test -f "$bundle_res/environment.sh"; then
- source "$bundle_res/environment.sh"
-fi
-
-# Strip out the argument added by the OS.
-if /bin/expr "x$1" : '^x-psn_' > /dev/null; then
- shift 1
-fi
-
-$EXEC "$bundle_contents/MacOS/$name-bin" "$@" $EXTRA_ARGS
diff --git a/data/osx/osx_startup_script.sh b/data/osx/osx_startup_script.sh
deleted file mode 100644
index 37905b8..0000000
--- a/data/osx/osx_startup_script.sh
+++ /dev/null
@@ -1,31 +0,0 @@
-#!/bin/sh
-
-name=`basename "$0"`
-tmp="$0"
-tmp=`dirname "$tmp"`
-tmp=`dirname "$tmp"`
-bundle=`dirname "$tmp"`
-bundle_contents="$bundle"/Contents
-bundle_res="$bundle_contents"/Resources
-bundle_lib="$bundle_res"/lib
-bundle_bin="$bundle_res"/bin
-bundle_data="$bundle_res"/share
-bundle_etc="$bundle_res"/etc
-
-export XDG_DATA_DIRS="$bundle_data"
-export GTK_DATA_PREFIX="$bundle_res"
-export GTK_EXE_PREFIX="$bundle_res"
-export GTK_PATH="$bundle_res"
-
-export GDK_PIXBUF_MODULE_FILE="$bundle_lib/gdk-pixbuf-2.0/2.10.0/loaders.cache"
-
-I18NDIR="$bundle_data/locale"
-
-# Strip out the argument added by the OS.
-if /bin/expr "x$1" : '^x-psn_' > /dev/null; then
- shift 1
-fi
-
-export GDK_DEBUG=interactive
-
-exec "$bundle_bin/zrythm" "$@"
diff --git a/data/osx/zrythm-gtk3.bundle b/data/osx/zrythm-gtk3.bundle
deleted file mode 100644
index 662d066..0000000
--- a/data/osx/zrythm-gtk3.bundle
+++ /dev/null
@@ -1,118 +0,0 @@
-<?xml version="1.0" standalone="no"?> <!--*- mode: xml -*-->
-<app-bundle>
-
- <meta>
- <!-- Where to pick up the GTK+ installation, icon themes,
- etc. Note that "${env:JHBUILD_PREFIX}" is evaluated to the
- value of the environment variable JHBUILD_PREFIX. You can
- define additional prefixes and refer to them in paths
- throughout this file on the form "${prefix:name}". This is
- useful for installing certain libraries or even the
- application itself separately. Note that JHBUILD_PREFIX is
- defined by jhbuild, so it you are not using jhbuild you can
- either define your own or just hardcode the path here.
- -->
- <!--<prefix name="jhbuild">${env:JHBUILD_PREFIX}</prefix>-->
- <prefix name="default">/usr/local</prefix>
- <prefix name="brew">/usr/local</prefix>
-
- <!-- The project directory is the default location of the created
- app. If you leave out the path, the current directory is
- used. Note the usage of an environment variable here again.
- -->
- <destination overwrite="yes">${env:HOME}/Desktop</destination>
-
- <image>
- <!-- Not implemented yet (DMG image). -->
- </image>
-
- <!-- Comment this out to keep the install names in binaries -->
- <run-install-name-tool/>
-
- <!-- Optionally specify a launcher script to use. If the
- application sets up everything needed itself, like
- environment variable, linker paths, etc, a launcher script is
- not needed. If the source path is left out, the default
- script will be used.
- -->
- <launcher-script>${project}/gtk3-launcher.sh</launcher-script >
-
- <!-- Not implemented: Optional runtime, could be python or mono
- for example.
- -->
- <!-- runtime copy="yes">/usr/bin/python</runtime -->
- <!-- Indicate the active gtk version to use. This is needed only
- for gtk+-3.0 projects. -->
- <gtk>gtk+-3.0</gtk>
- </meta>
-
- <!-- The special macro "${project}" refers to the directory where
- this bundle file is located. The application name and bundle
- identifier are taken from the plist file.
- -->
- <plist>${project}/Info.plist</plist>
-
- <main-binary dest="${bundle}/bin/zrythm">${project}/../../build/zrythm</main-binary>
-
- <!-- Copy in the input methods. Dunno if they actually work with
- OSX. Note the ${gtkdir} macro, which expands to the correct
- library subdirectory for the specified gtk version. -->
- <binary>
- ${prefix:brew}/lib/${gtkdir}/${pkg:${gtk}:gtk_binary_version}/immodules/*.so
- </binary>
-
-<!-- And the print backends -->
- <binary>
- ${prefix:brew}/lib/${gtkdir}/${pkg:${gtk}:gtk_binary_version}/printbackends/*.so
- </binary>
-
-<!-- Starting with 2.24, gdk-pixbuf installs into its own directory. -->
- <binary>
- ${prefix:brew}/lib/gdk-pixbuf-2.0/${pkg:gdk-pixbuf-2.0:gdk_pixbuf_binary_version}/loaders/*.so
- </binary>
-
-<!-- No longer needed for pango >= 1.38
- <binary>
- ${prefix:brew}/lib/pango/${pkg:pango:pango_module_version}/modules/
- </binary>
--->
-
- <!-- Translation filenames, one for each program or library that you
- want to copy in to the bundle. The "dest" attribute is
- optional, as usual. Bundler will find all translations of that
- library/program under the indicated directory and copy them.-->
- <translations name="zrythm" dest="${bundle}/locale">
- ${project}/../../po
- </translations>
-
-
- <!-- Data to copy in, usually Glade/UI files, images, sounds files
- etc. The destination inside the bundle can be specified if the
- files should end up at a different location, by using the
- "dest" property. The destination must then start with the macro
- "${bundle}", which refers to the bundle root directory.
- -->
- <!-- data>
- ${prefix}/share/gtk3-demo
- </data -->
-
- <!-- Copy in the themes data. You may want to trim this to save space
- in your bundle. -->
- <data>
- ${prefix:brew}/share/themes
- </data>
-
- <data>
- ${prefix:brew}/share/icons
- </data>
-
- <!-- Copy icons. Note that the .icns file is an Apple format which
- contains up to 4 sizes of icon. You can use
- /Developer/Applications/Utilities/Icon Composer.app to import
- artwork and create the file. -->
- <data dest="${bundle}/Contents/Resources">
- ${project}/zrythm.icns
- </data>
-
- </app-bundle>
-
diff --git a/data/osx/zrythm.icns b/data/osx/zrythm.icns
deleted file mode 100644
index b613654..0000000
--- a/data/osx/zrythm.icns
+++ /dev/null
Binary files differ
diff --git a/data/settings.ini b/data/settings.ini
index d1c17cd..7149c6c 100644
--- a/data/settings.ini
+++ b/data/settings.ini
@@ -1,3 +1,20 @@
+# Copyright (C) 2019 Alexandros Theodotou <alex at zrythm dot org>
+#
+# This file is part of Zrythm
+#
+# Zrythm is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Affero General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# Zrythm 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 Affero General Public License for more details.
+#
+# You should have received a copy of the GNU Affero General Public License
+# along with Zrythm. If not, see <https://www.gnu.org/licenses/>.
+
[Settings]
gtk-theme-name=Windows10
gtk-font-name=Segoe UI 9
diff --git a/data/zrythm.desktop b/data/zrythm.desktop
index 19c12da..179b007 100644
--- a/data/zrythm.desktop
+++ b/data/zrythm.desktop
@@ -1,3 +1,20 @@
+# Copyright (C) 2019 Alexandros Theodotou <alex at zrythm dot org>
+#
+# This file is part of Zrythm
+#
+# Zrythm is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Affero General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# Zrythm 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 Affero General Public License for more details.
+#
+# You should have received a copy of the GNU Affero General Public License
+# along with Zrythm. If not, see <https://www.gnu.org/licenses/>.
+
[Desktop Entry]
Name=Zrythm
Version=1.0
diff --git a/doc/Doxyfile-mcss.in b/doc/Doxyfile-mcss.in
index fe5531c..892d3d5 100644
--- a/doc/Doxyfile-mcss.in
+++ b/doc/Doxyfile-mcss.in
@@ -1,3 +1,21 @@
+# Copyright (C) 2019 Alexandros Theodotou <alex at zrythm dot org>
+#
+# This file is part of Zrythm
+#
+# Zrythm is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Affero General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# Zrythm 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 Affero General Public License for more details.
+#
+# You should have received a copy of the GNU Affero General Public License
+# along with Zrythm. If not, see <https://www.gnu.org/licenses/>.
+#
+
@INCLUDE = Doxyfile.cfg
GENERATE_HTML = NO
GENERATE_XML = YES
diff --git a/doc/Doxyfile.cfg.in b/doc/Doxyfile.cfg.in
index dfd5b9d..da3979c 100644
--- a/doc/Doxyfile.cfg.in
+++ b/doc/Doxyfile.cfg.in
@@ -1,4 +1,21 @@
-# Doxyfile 1.8.13
+# Copyright (C) 2019 Alexandros Theodotou <alex at zrythm dot org>
+#
+# This file is part of Zrythm
+#
+# Zrythm is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Affero General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# Zrythm 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 Affero General Public License for more details.
+#
+# You should have received a copy of the GNU Affero General Public License
+# along with Zrythm. If not, see <https://www.gnu.org/licenses/>.
+#
+# ----------------------------------
# This file describes the settings to be used by the documentation system
# doxygen (www.doxygen.org) for a project.
diff --git a/doc/cyaml_schemas.h b/doc/cyaml_schemas.h
index c3404cd..567e94c 100644
--- a/doc/cyaml_schemas.h
+++ b/doc/cyaml_schemas.h
@@ -1,4 +1,21 @@
/**
+ * Copyright (C) 2019 Alexandros Theodotou <alex at zrythm dot org>
+ *
+ * This file is part of Zrythm
+ *
+ * Zrythm is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Zrythm 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 Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with Zrythm. If not, see <https://www.gnu.org/licenses/>.
+ *
* \page cyaml_schemas Cyaml Schemas
*
* \section introduction_cyaml Introduction
diff --git a/doc/mainpage.h b/doc/mainpage.h
index 049b959..00c7ed0 100644
--- a/doc/mainpage.h
+++ b/doc/mainpage.h
@@ -1,4 +1,21 @@
/**
+ * Copyright (C) 2019 Alexandros Theodotou <alex at zrythm dot org>
+ *
+ * This file is part of Zrythm
+ *
+ * Zrythm is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Zrythm 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 Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with Zrythm. If not, see <https://www.gnu.org/licenses/>.
+ *
*
* \mainpage Documentation
*
diff --git a/doc/meson.build b/doc/meson.build
index 77f2095..1f9f1bf 100644
--- a/doc/meson.build
+++ b/doc/meson.build
@@ -1,3 +1,20 @@
+# Copyright (C) 2019 Alexandros Theodotou <alex at zrythm dot org>
+#
+# This file is part of Zrythm
+#
+# Zrythm is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Affero General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# Zrythm 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 Affero General Public License for more details.
+#
+# You should have received a copy of the GNU Affero General Public License
+# along with Zrythm. If not, see <https://www.gnu.org/licenses/>.
+
doxyfile = configure_file (
output: 'Doxyfile.cfg',
input: 'Doxyfile.cfg.in',
diff --git a/doc/processing_cycle.h b/doc/processing_cycle.h
index ff631e5..9896b04 100644
--- a/doc/processing_cycle.h
+++ b/doc/processing_cycle.h
@@ -1,4 +1,21 @@
/**
+ * Copyright (C) 2019 Alexandros Theodotou <alex at zrythm dot org>
+ *
+ * This file is part of Zrythm
+ *
+ * Zrythm is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Zrythm 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 Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with Zrythm. If not, see <https://www.gnu.org/licenses/>.
+ *
* \page processing_cycle The Processing Cycle
*
* \section introduction_processing_cycle Introduction
diff --git a/doc/release_checklist.h b/doc/release_checklist.h
index c2eb71c..b4f301a 100644
--- a/doc/release_checklist.h
+++ b/doc/release_checklist.h
@@ -1,4 +1,21 @@
/**
+ * Copyright (C) 2019 Alexandros Theodotou <alex at zrythm dot org>
+ *
+ * This file is part of Zrythm
+ *
+ * Zrythm is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Zrythm 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 Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with Zrythm. If not, see <https://www.gnu.org/licenses/>.
+ *
* \page release_checklist Release Checklist
*
* \section release_checklist_checklist Checklist
diff --git a/doc/weblate.h b/doc/weblate.h
index 4a9a2d4..99bea56 100644
--- a/doc/weblate.h
+++ b/doc/weblate.h
@@ -1,4 +1,21 @@
/**
+ * Copyright (C) 2019 Alexandros Theodotou <alex at zrythm dot org>
+ *
+ * This file is part of Zrythm
+ *
+ * Zrythm is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Zrythm 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 Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with Zrythm. If not, see <https://www.gnu.org/licenses/>.
+ *
* \page weblate Weblate Translations
*
* \section introduction_weblate Introduction
diff --git a/ext/README b/ext/README
new file mode 100644
index 0000000..21b100d
--- /dev/null
+++ b/ext/README
@@ -0,0 +1 @@
+These are not part of Zrythm, but are used with Zrythm.
diff --git a/ext/audio_decoder/meson.build b/ext/audio_decoder/meson.build
index f13d9cb..4bbc65c 100644
--- a/ext/audio_decoder/meson.build
+++ b/ext/audio_decoder/meson.build
@@ -1,3 +1,20 @@
+# Copyright (C) 2019 Alexandros Theodotou <alex at zrythm dot org>
+#
+# This file is part of Zrythm
+#
+# Zrythm is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Affero General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# Zrythm 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 Affero General Public License for more details.
+#
+# You should have received a copy of the GNU Affero General Public License
+# along with Zrythm. If not, see <https://www.gnu.org/licenses/>.
+
audio_decoder_srcs = [
'ad_soundfile.c',
'ad_ffmpeg.c',
diff --git a/ext/libcyaml/meson.build b/ext/libcyaml/meson.build
index b60df97..10e9486 100644
--- a/ext/libcyaml/meson.build
+++ b/ext/libcyaml/meson.build
@@ -1,3 +1,20 @@
+# Copyright (C) 2019 Alexandros Theodotou <alex at zrythm dot org>
+#
+# This file is part of Zrythm
+#
+# Zrythm is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Affero General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# Zrythm 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 Affero General Public License for more details.
+#
+# You should have received a copy of the GNU Affero General Public License
+# along with Zrythm. If not, see <https://www.gnu.org/licenses/>.
+
cyaml_inc = [
include_directories ('include'),
]
diff --git a/ext/meson.build b/ext/meson.build
index 7e553fe..ddf4274 100644
--- a/ext/meson.build
+++ b/ext/meson.build
@@ -1,3 +1,20 @@
+# Copyright (C) 2019 Alexandros Theodotou <alex at zrythm dot org>
+#
+# This file is part of Zrythm
+#
+# Zrythm is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Affero General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# Zrythm 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 Affero General Public License for more details.
+#
+# You should have received a copy of the GNU Affero General Public License
+# along with Zrythm. If not, see <https://www.gnu.org/licenses/>.
+
subdir ('audio_decoder')
subdir ('libcyaml')
subdir ('midilib')
diff --git a/ext/midilib/meson.build b/ext/midilib/meson.build
index 412a7f1..a457240 100644
--- a/ext/midilib/meson.build
+++ b/ext/midilib/meson.build
@@ -1,3 +1,20 @@
+# Copyright (C) 2019 Alexandros Theodotou <alex at zrythm dot org>
+#
+# This file is part of Zrythm
+#
+# Zrythm is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Affero General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# Zrythm 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 Affero General Public License for more details.
+#
+# You should have received a copy of the GNU Affero General Public License
+# along with Zrythm. If not, see <https://www.gnu.org/licenses/>.
+
midilib = static_library (
'midilib',
join_paths ('src', 'midifile.c'),
diff --git a/ext/zix/meson.build b/ext/zix/meson.build
index 5a964da..d744d7d 100644
--- a/ext/zix/meson.build
+++ b/ext/zix/meson.build
@@ -1 +1,18 @@
+# Copyright (C) 2019 Alexandros Theodotou <alex at zrythm dot org>
+#
+# This file is part of Zrythm
+#
+# Zrythm is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Affero General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# Zrythm 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 Affero General Public License for more details.
+#
+# You should have received a copy of the GNU Affero General Public License
+# along with Zrythm. If not, see <https://www.gnu.org/licenses/>.
+
subdir ('zix')
diff --git a/ext/zix/zix/meson.build b/ext/zix/zix/meson.build
index 07e1a67..ab746ea 100644
--- a/ext/zix/zix/meson.build
+++ b/ext/zix/zix/meson.build
@@ -1,3 +1,20 @@
+# Copyright (C) 2019 Alexandros Theodotou <alex at zrythm dot org>
+#
+# This file is part of Zrythm
+#
+# Zrythm is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Affero General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# Zrythm 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 Affero General Public License for more details.
+#
+# You should have received a copy of the GNU Affero General Public License
+# along with Zrythm. If not, see <https://www.gnu.org/licenses/>.
+
zix_srcs = [
'ring.c',
]
diff --git a/flatpak/org.zrythm.Zrythm.json.README b/flatpak/org.zrythm.Zrythm.json.README
new file mode 100644
index 0000000..53c391e
--- /dev/null
+++ b/flatpak/org.zrythm.Zrythm.json.README
@@ -0,0 +1,17 @@
+Copyright (C) 2019 Alexandros Theodotou <alex at zrythm dot org>
+
+This file is part of Zrythm
+
+Zrythm is free software: you can redistribute it and/or modify
+it under the terms of the GNU Affero General Public License as published by
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+Zrythm 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 Affero General Public License for more details.
+
+You should have received a copy of the GNU Affero General Public License
+along with Zrythm. If not, see <https://www.gnu.org/licenses/>.
+
diff --git a/inc/Wrapper.h b/inc/Wrapper.h
index ced507f..e28ae6c 100644
--- a/inc/Wrapper.h
+++ b/inc/Wrapper.h
@@ -1 +1,20 @@
+/*
+ * Copyright (C) 2019 Alexandros Theodotou <alex at zrythm dot org>
+ *
+ * This file is part of Zrythm
+ *
+ * Zrythm is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Zrythm 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 Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with Zrythm. If not, see <https://www.gnu.org/licenses/>.
+ */
+
void show_on_top(void);
diff --git a/inc/actions/create_automation_selections_action.h b/inc/actions/create_automation_selections_action.h
new file mode 100644
index 0000000..b9d45a9
--- /dev/null
+++ b/inc/actions/create_automation_selections_action.h
@@ -0,0 +1,71 @@
+/*
+ * Copyright (C) 2019 Alexandros Theodotou <alex at zrythm dot org>
+ *
+ * This file is part of Zrythm
+ *
+ * Zrythm is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Zrythm 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 Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with Zrythm. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+#ifndef __UNDO_CREATE_AUTOMATION_SELECTIONS_ACTION_H__
+#define __UNDO_CREATE_AUTOMATION_SELECTIONS_ACTION_H__
+
+#include "actions/undoable_action.h"
+
+typedef struct AutomationSelections
+ AutomationSelections;
+
+/**
+ * It currently "creates" the current selection so
+ * that it's undoable.
+ *
+ * It does nothing on perform due to how the
+ * arrangers currently work. This might change in
+ * the future.
+ */
+typedef struct CreateAutomationSelectionsAction
+{
+ UndoableAction parent_instance;
+
+ /**
+ * A clone of the automation selections at the time.
+ */
+ AutomationSelections * ts;
+} CreateAutomationSelectionsAction;
+
+/**
+ * The given AutomationSelections must already
+ * contain the created selections in the transient
+ * arrays.
+ */
+UndoableAction *
+create_automation_selections_action_new (
+ AutomationSelections * ts);
+
+int
+create_automation_selections_action_do (
+ CreateAutomationSelectionsAction * self);
+
+int
+create_automation_selections_action_undo (
+ CreateAutomationSelectionsAction * self);
+
+char *
+create_automation_selections_action_stringize (
+ CreateAutomationSelectionsAction * self);
+
+void
+create_automation_selections_action_free (
+ CreateAutomationSelectionsAction * self);
+
+#endif
diff --git a/inc/actions/create_chord_selections_action.h b/inc/actions/create_chord_selections_action.h
new file mode 100644
index 0000000..cd36255
--- /dev/null
+++ b/inc/actions/create_chord_selections_action.h
@@ -0,0 +1,71 @@
+/*
+ * Copyright (C) 2019 Alexandros Theodotou <alex at zrythm dot org>
+ *
+ * This file is part of Zrythm
+ *
+ * Zrythm is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Zrythm 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 Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with Zrythm. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+#ifndef __UNDO_CREATE_CHORD_SELECTIONS_ACTION_H__
+#define __UNDO_CREATE_CHORD_SELECTIONS_ACTION_H__
+
+#include "actions/undoable_action.h"
+
+typedef struct ChordSelections
+ ChordSelections;
+
+/**
+ * It currently "creates" the current selection so
+ * that it's undoable.
+ *
+ * It does nothing on perform due to how the
+ * arrangers currently work. This might change in
+ * the future.
+ */
+typedef struct CreateChordSelectionsAction
+{
+ UndoableAction parent_instance;
+
+ /**
+ * A clone of the chord selections at the time.
+ */
+ ChordSelections * ts;
+} CreateChordSelectionsAction;
+
+/**
+ * The given ChordSelections must already
+ * contain the created selections in the transient
+ * arrays.
+ */
+UndoableAction *
+create_chord_selections_action_new (
+ ChordSelections * ts);
+
+int
+create_chord_selections_action_do (
+ CreateChordSelectionsAction * self);
+
+int
+create_chord_selections_action_undo (
+ CreateChordSelectionsAction * self);
+
+char *
+create_chord_selections_action_stringize (
+ CreateChordSelectionsAction * self);
+
+void
+create_chord_selections_action_free (
+ CreateChordSelectionsAction * self);
+
+#endif
diff --git a/inc/actions/dir.h b/inc/actions/dir.h
index 4df4e9b..e0fbcaa 100644
--- a/inc/actions/dir.h
+++ b/inc/actions/dir.h
@@ -1,5 +1,24 @@
+/*
+ * Copyright (C) 2019 Alexandros Theodotou <alex at zrythm dot org>
+ *
+ * This file is part of Zrythm
+ *
+ * Zrythm is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Zrythm 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 Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with Zrythm. If not, see <https://www.gnu.org/licenses/>.
+ */
+
/**
- * @dir inc/actions
+ * @dir inc/actions
*
* Action-related code (undo/redo, zoom, etc.).
*/
diff --git a/inc/actions/duplicate_automation_selections_action.h b/inc/actions/duplicate_automation_selections_action.h
new file mode 100644
index 0000000..8e35c65
--- /dev/null
+++ b/inc/actions/duplicate_automation_selections_action.h
@@ -0,0 +1,66 @@
+/*
+ * Copyright (C) 2019 Alexandros Theodotou <alex at zrythm dot org>
+ *
+ * This file is part of Zrythm
+ *
+ * Zrythm is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Zrythm 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 Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with Zrythm. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+#ifndef __UNDO_DUPLICATE_AUTOMATION_SELECTIONS_ACTION_H__
+#define __UNDO_DUPLICATE_AUTOMATION_SELECTIONS_ACTION_H__
+
+#include "actions/undoable_action.h"
+
+typedef struct AutomationSelections
+ AutomationSelections;
+
+typedef struct DuplicateAutomationSelectionsAction
+{
+ UndoableAction parent_instance;
+
+ /**
+ * A clone of the automation selections at the time.
+ */
+ AutomationSelections * ts;
+
+ /** Ticks diff. */
+ long ticks;
+
+ /** Value (# of Tracks) diff. */
+ int delta;
+} DuplicateAutomationSelectionsAction;
+
+UndoableAction *
+duplicate_automation_selections_action_new (
+ AutomationSelections * ts,
+ long ticks,
+ int delta);
+
+int
+duplicate_automation_selections_action_do (
+ DuplicateAutomationSelectionsAction * self);
+
+int
+duplicate_automation_selections_action_undo (
+ DuplicateAutomationSelectionsAction * self);
+
+char *
+duplicate_automation_selections_action_stringize (
+ DuplicateAutomationSelectionsAction * self);
+
+void
+duplicate_automation_selections_action_free (
+ DuplicateAutomationSelectionsAction * self);
+
+#endif
diff --git a/inc/actions/duplicate_chord_selections_action.h b/inc/actions/duplicate_chord_selections_action.h
new file mode 100644
index 0000000..51a01af
--- /dev/null
+++ b/inc/actions/duplicate_chord_selections_action.h
@@ -0,0 +1,66 @@
+/*
+ * Copyright (C) 2019 Alexandros Theodotou <alex at zrythm dot org>
+ *
+ * This file is part of Zrythm
+ *
+ * Zrythm is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Zrythm 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 Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with Zrythm. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+#ifndef __UNDO_DUPLICATE_CHORD_SELECTIONS_ACTION_H__
+#define __UNDO_DUPLICATE_CHORD_SELECTIONS_ACTION_H__
+
+#include "actions/undoable_action.h"
+
+typedef struct ChordSelections
+ ChordSelections;
+
+typedef struct DuplicateChordSelectionsAction
+{
+ UndoableAction parent_instance;
+
+ /**
+ * A clone of the chord selections at the time.
+ */
+ ChordSelections * ts;
+
+ /** Ticks diff. */
+ long ticks;
+
+ /** Value (# of Tracks) diff. */
+ int delta;
+} DuplicateChordSelectionsAction;
+
+UndoableAction *
+duplicate_chord_selections_action_new (
+ ChordSelections * ts,
+ long ticks,
+ int delta);
+
+int
+duplicate_chord_selections_action_do (
+ DuplicateChordSelectionsAction * self);
+
+int
+duplicate_chord_selections_action_undo (
+ DuplicateChordSelectionsAction * self);
+
+char *
+duplicate_chord_selections_action_stringize (
+ DuplicateChordSelectionsAction * self);
+
+void
+duplicate_chord_selections_action_free (
+ DuplicateChordSelectionsAction * self);
+
+#endif
diff --git a/inc/actions/move_automation_selections_action.h b/inc/actions/move_automation_selections_action.h
new file mode 100644
index 0000000..49d4b3a
--- /dev/null
+++ b/inc/actions/move_automation_selections_action.h
@@ -0,0 +1,66 @@
+/*
+ * Copyright (C) 2019 Alexandros Theodotou <alex at zrythm dot org>
+ *
+ * This file is part of Zrythm
+ *
+ * Zrythm is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Zrythm 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 Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with Zrythm. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+#ifndef __UNDO_MOVE_AUTOMATION_SELECTIONS_ACTION_H__
+#define __UNDO_MOVE_AUTOMATION_SELECTIONS_ACTION_H__
+
+#include "actions/undoable_action.h"
+
+typedef struct AutomationSelections
+ AutomationSelections;
+
+typedef struct MoveAutomationSelectionsAction
+{
+ UndoableAction parent_instance;
+
+ /** Ticks moved. */
+ long ticks;
+
+ /** Tracks moved. */
+ int delta;
+
+ int first_call;
+
+ /** Automation selections clone. */
+ AutomationSelections * ts;
+} MoveAutomationSelectionsAction;
+
+UndoableAction *
+move_automation_selections_action_new (
+ AutomationSelections * ts,
+ long ticks,
+ int delta);
+
+int
+move_automation_selections_action_do (
+ MoveAutomationSelectionsAction * self);
+
+int
+move_automation_selections_action_undo (
+ MoveAutomationSelectionsAction * self);
+
+char *
+move_automation_selections_action_stringize (
+ MoveAutomationSelectionsAction * self);
+
+void
+move_automation_selections_action_free (
+ MoveAutomationSelectionsAction * self);
+
+#endif
diff --git a/inc/actions/move_chord_selections_action.h b/inc/actions/move_chord_selections_action.h
new file mode 100644
index 0000000..e63ee71
--- /dev/null
+++ b/inc/actions/move_chord_selections_action.h
@@ -0,0 +1,66 @@
+/*
+ * Copyright (C) 2019 Alexandros Theodotou <alex at zrythm dot org>
+ *
+ * This file is part of Zrythm
+ *
+ * Zrythm is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Zrythm 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 Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with Zrythm. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+#ifndef __UNDO_MOVE_CHORD_SELECTIONS_ACTION_H__
+#define __UNDO_MOVE_CHORD_SELECTIONS_ACTION_H__
+
+#include "actions/undoable_action.h"
+
+typedef struct ChordSelections
+ ChordSelections;
+
+typedef struct MoveChordSelectionsAction
+{
+ UndoableAction parent_instance;
+
+ /** Ticks moved. */
+ long ticks;
+
+ /** Tracks moved. */
+ int delta;
+
+ int first_call;
+
+ /** Chord selections clone. */
+ ChordSelections * ts;
+} MoveChordSelectionsAction;
+
+UndoableAction *
+move_chord_selections_action_new (
+ ChordSelections * ts,
+ long ticks,
+ int delta);
+
+int
+move_chord_selections_action_do (
+ MoveChordSelectionsAction * self);
+
+int
+move_chord_selections_action_undo (
+ MoveChordSelectionsAction * self);
+
+char *
+move_chord_selections_action_stringize (
+ MoveChordSelectionsAction * self);
+
+void
+move_chord_selections_action_free (
+ MoveChordSelectionsAction * self);
+
+#endif
diff --git a/inc/audio/automation_curve.h b/inc/audio/automation_curve.h
index cd10127..c075dac 100644
--- a/inc/audio/automation_curve.h
+++ b/inc/audio/automation_curve.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2018-2019 Alexandros Theodotou
+ * Copyright (C) 2018-2019 Alexandros Theodotou <alex at zrythm dot org>
*
* This file is part of Zrythm
*
@@ -17,11 +17,27 @@
* along with Zrythm. If not, see <https://www.gnu.org/licenses/>.
*/
+/**
+ * \file
+ *
+ * AutomationCurve API.
+ */
+
#ifndef __AUDIO_AUTOMATION_CURVE_H__
#define __AUDIO_AUTOMATION_CURVE_H__
#include "audio/position.h"
+typedef struct AutomationTrack AutomationTrack;
+typedef struct _AutomationCurveWidget
+ AutomationCurveWidget;
+
+/**
+ * @addtogroup audio
+ *
+ * @{
+ */
+
#define AP_MAX_CURVINESS 6.f
/*#define AP_MIN_CURVINESS \
//(1.f / AP_MAX_CURVINESS)*/
@@ -30,9 +46,9 @@
(AP_MAX_CURVINESS - AP_MIN_CURVINESS)
#define AP_MID_CURVINESS 1.f
-typedef struct AutomationTrack AutomationTrack;
-typedef struct _AutomationCurveWidget AutomationCurveWidget;
-
+/**
+ * Type of AutomationCurve.
+ */
typedef enum AutomationCurveType
{
AUTOMATION_CURVE_TYPE_BOOL,
@@ -40,25 +56,30 @@ typedef enum AutomationCurveType
AUTOMATION_CURVE_TYPE_FLOAT
} AutomationCurveType;
+
+/**
+ * The curve between two AutomationPoint's.
+ */
typedef struct AutomationCurve
{
/**
* Midway position between previous ap and next ap.
*/
- Position pos;
+ Position pos;
/** Curviness. */
- float curviness;
- AutomationCurveType type;
+ float curviness;
+ AutomationCurveType type;
/** Pointer back to parent. */
- AutomationTrack * at;
- AutomationCurveWidget * widget;
+ Region * region;
+
+ AutomationCurveWidget * widget;
/** Index in the automation track, for faster
* performance when getting ap before/after
* curve. */
- int index;
+ int index;
} AutomationCurve;
static const cyaml_strval_t
@@ -102,43 +123,64 @@ automation_curve_init_loaded (
AutomationCurve * ac);
/**
- * Creates curviness point in given track at given Position
+ * Creates an AutomationCurve.
+ *
+ * @param region The Region, used to figure out the
+ * AutomationCurve type.
*/
AutomationCurve *
-automation_curve_new (AutomationTrack * at,
- Position * pos);
-
-/**
- * Frees the automation point.
- */
-void
-automation_curve_free (AutomationCurve * ap);
+automation_curve_new (
+ Region * region,
+ const Position * pos);
/**
* The function to return a point on the curve.
*
* See https://stackoverflow.com/questions/17623152/how-map-tween-a-number-based-on-a-dynamic-curve
+ *
+ * @param ac The start point (0, 0).
+ * @param x X-coordinate in px.
+ * @param width Total width in px.
+ * @param height Total height in px.
*/
double
-automation_curve_get_y_px (AutomationCurve * start_ap, ///< start point (0, 0)
- double x, ///< x coordinate in px
- double width, ///< total width in px
- double height); ///< total height in px
+automation_curve_get_y_px (
+ AutomationCurve * ac,
+ double x,
+ double width,
+ double height);
/**
- * The function.
+ * TODO add description.
*
* See https://stackoverflow.com/questions/17623152/how-map-tween-a-number-based-on-a-dynamic-curve
+ * @param x X-coordinate.
+ * @param curviness Curviness variable.
+ * @param start_at_1 Start at lower point.
*/
double
automation_curve_get_y_normalized (
- double x, ///< x coordinate
+ double x,
double curviness,
- int start_at_1); ///< start at lower point
+ int start_at_1);
+/**
+ * Sets the curviness of the AutomationCurve.
+ */
void
-automation_curve_set_curviness (AutomationCurve * ac, float curviness);
+automation_curve_set_curviness (
+ AutomationCurve * ac,
+ float curviness);
-#endif // __AUDIO_AUTOMATION_CURVE_H__
+/**
+ * Frees the automation point.
+ */
+void
+automation_curve_free (
+ AutomationCurve * ap);
+/**
+ * @}
+ */
+#endif // __AUDIO_AUTOMATION_CURVE_H__
diff --git a/inc/audio/automation_point.h b/inc/audio/automation_point.h
index e7f859d..18527c1 100644
--- a/inc/audio/automation_point.h
+++ b/inc/audio/automation_point.h
@@ -80,14 +80,16 @@ typedef struct AutomationPoint
/**
* Pointer back to parent.
*/
- int track_pos;
- int at_index;
- AutomationTrack * at;
+ Region * region;
/** GUI Widget. */
AutomationPointWidget * widget;
- /** Index in the automation track, for faster
+ /** Used in clones to identify a region instead of
+ * cloning the whole Region. */
+ char * region_name;
+
+ /** Index in the region, for faster
* performance when getting ap before/after
* curve. */
int index;
@@ -114,12 +116,6 @@ automation_point_fields_schema[] =
CYAML_FIELD_INT (
"index", CYAML_FLAG_DEFAULT,
AutomationPoint, index),
- CYAML_FIELD_INT (
- "track_pos", CYAML_FLAG_DEFAULT,
- AutomationPoint, track_pos),
- CYAML_FIELD_INT (
- "at_index", CYAML_FLAG_DEFAULT,
- AutomationPoint, at_index),
CYAML_FIELD_END
};
@@ -175,14 +171,14 @@ automation_point_update_fvalue (
ArrangerObjectUpdateFlag update_flag);
/**
- * Sets the AutomationTrack and the index in the
- * AutomationTrack that the AutomationPoint
+ * Sets the Region and the index in the
+ * region that the AutomationPoint
* belongs to, in all its counterparts.
*/
void
-automation_point_set_automation_track_and_index (
+automation_point_set_region_and_index (
AutomationPoint * _ap,
- AutomationTrack * at,
+ Region * region,
int index);
/**
diff --git a/inc/audio/automation_region.h b/inc/audio/automation_region.h
new file mode 100644
index 0000000..3f64450
--- /dev/null
+++ b/inc/audio/automation_region.h
@@ -0,0 +1,164 @@
+/*
+ * Copyright (C) 2019 Alexandros Theodotou <alex at zrythm dot org>
+ *
+ * This file is part of Zrythm
+ *
+ * Zrythm is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Zrythm 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 Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with Zrythm. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+/**
+ * \file
+ *
+ * API for automation Region's.
+ */
+
+#ifndef __AUDIO_AUTOMATION_REGION_H__
+#define __AUDIO_AUTOMATION_REGION_H__
+
+typedef struct Track Track;
+typedef struct Position Position;
+typedef struct AutomationPoint AutomationPoint;
+typedef struct AutomationCurve AutomationCurve;
+typedef struct Region Region;
+
+/**
+ * @addtogroup audio
+ *
+ * @{
+ */
+
+/**
+ * Creates a new Region for automation.
+ *
+ * @param is_main If this is 1 it
+ * will create the additional Region (
+ * main_transient).
+ */
+Region *
+automation_region_new (
+ const Position * start_pos,
+ const Position * end_pos,
+ const int is_main);
+
+/**
+ * Prints the automation in this Region.
+ */
+void
+automation_region_print_automation (
+ Region * self);
+
+/**
+ * Forces sort of the automation points.
+ */
+void
+automation_region_force_sort (
+ Region * self);
+
+/**
+ * Adds automation point and optionally generates
+ * curve points accordingly.
+ *
+ * @param gen_curve_points Generate AutomationCurve's.
+ */
+void
+automation_region_add_ap (
+ Region * self,
+ AutomationPoint * ap,
+ int gen_curves);
+
+/**
+ * Adds the given AutomationCurve.
+ */
+void
+automation_region_add_ac (
+ Region * self,
+ AutomationCurve * ac);
+
+/**
+ * Returns the AutomationPoint before the position.
+ */
+AutomationPoint *
+automation_region_get_prev_ap (
+ Region * self,
+ AutomationPoint * ap);
+
+/**
+ * Returns the AutomationPoint after the position.
+ */
+AutomationPoint *
+automation_region_get_next_ap (
+ Region * self,
+ AutomationPoint * ap);
+
+/**
+ * Returns the AutomationPoint before the given
+ * AutomationCurve.
+ */
+AutomationPoint *
+automation_region_get_ap_before_curve (
+ Region * self,
+ AutomationCurve * ac);
+
+/**
+ * Returns the ap after the curve point.
+ */
+AutomationPoint *
+automation_region_get_ap_after_curve (
+ Region * self,
+ AutomationCurve * ac);
+
+/**
+ * Returns the curve point right after the given ap
+ */
+AutomationCurve *
+automation_region_get_next_curve_ac (
+ Region * self,
+ AutomationPoint * ap);
+
+/**
+ * Removes the given AutomationPoint from the Region.
+ *
+ * @param free Optionally free the AutomationPoint.
+ */
+void
+automation_region_remove_ap (
+ Region * self,
+ AutomationPoint * ap,
+ int free);
+
+/**
+ * Removes the given AutomationCurve from the Region.
+ *
+ * @param free Optionally free the AutomationCurve.
+ */
+void
+automation_region_remove_ac (
+ Region * self,
+ AutomationCurve * ac,
+ int free);
+
+/**
+ * Frees members only but not the Region itself.
+ *
+ * Regions should be free'd using region_free.
+ */
+void
+automation_region_free_members (
+ Region * self);
+
+/**
+ * @}
+ */
+
+#endif // __AUDIO_AUTOMATION_REGION_H__
diff --git a/inc/audio/automation_track.h b/inc/audio/automation_track.h
index 187728e..4519965 100644
--- a/inc/audio/automation_track.h
+++ b/inc/audio/automation_track.h
@@ -52,20 +52,15 @@ typedef struct AutomationTrack
*/
Track * track;
- /**
- * The automation points.
- *
- * Must always stay sorted by position.
- */
- AutomationPoint * aps[MAX_AUTOMATION_POINTS];
- int num_aps;
- AutomationCurve * acs[MAX_AUTOMATION_POINTS];
- int num_acs;
-
/** Whether it has been created by the user
* yet or not. */
int created;
+ /** The automation Region's. */
+ Region ** regions;
+ int num_regions;
+ int regions_size;
+
/**
* Whether visible or not.
*
@@ -93,14 +88,6 @@ static const cyaml_schema_field_t
CYAML_FLAG_DEFAULT,
AutomationTrack, automatable,
automatable_fields_schema),
- CYAML_FIELD_SEQUENCE_COUNT (
- "aps", CYAML_FLAG_DEFAULT,
- AutomationTrack, aps, num_aps,
- &automation_point_schema, 0, CYAML_UNLIMITED),
- CYAML_FIELD_SEQUENCE_COUNT (
- "acs", CYAML_FLAG_DEFAULT,
- AutomationTrack, acs, num_acs,
- &automation_curve_schema, 0, CYAML_UNLIMITED),
CYAML_FIELD_INT (
"created", CYAML_FLAG_DEFAULT,
AutomationTrack, created),
@@ -128,112 +115,40 @@ automation_track_init_loaded (
AutomationTrack * self);
/**
- * Creates an automation track for the given automatable
+ * Creates an automation track for the given
+ * automatable.
*/
AutomationTrack *
automation_track_new (Automatable * automatable);
/**
- * Sets the automatable to the automation track and updates the GUI
- */
-void
-automation_track_set_automatable (
- AutomationTrack * automation_track,
- Automatable * a);
-
-/**
- * Frees the automation track.
+ * Adds an automation Region to the AutomationTrack.
*/
void
-automation_track_free (AutomationTrack * at);
-
-void
-automation_track_print_automation_points (
- AutomationTrack * at);
-
-/**
- * Forces sort of the automation points.
- */
-void
-automation_track_force_sort (AutomationTrack * at);
-
-/**
- * Adds automation point and optionally generates curve points accordingly.
- */
-void
-automation_track_add_ap (
- AutomationTrack * at,
- AutomationPoint * ap,
- int gen_widget,
- int generate_curve_points);
+automation_track_add_region (
+ AutomationTrack * self,
+ Region * region);
/**
- * Adds automation curve.
+ * Sets the automatable to the automation track and updates the GUI
*/
void
-automation_track_add_ac (
- AutomationTrack * at,
- AutomationCurve * ac);
-
-/**
- * Returns the automation point before the position.
- */
-AutomationPoint *
-automation_track_get_prev_ap (AutomationTrack * at,
- AutomationPoint * _ap);
-
-/**
- * Returns the automation point after the position.
- */
-AutomationPoint *
-automation_track_get_next_ap (AutomationTrack * at,
- AutomationPoint * _ap);
-
-AutomationPoint *
-automation_track_get_ap_before_curve (
- AutomationTrack * at,
- AutomationCurve * ac);
-
-/**
- * Returns the ap after the curve point.
- */
-AutomationPoint *
-automation_track_get_ap_after_curve (
- AutomationTrack * at,
- AutomationCurve * ac);
-
-/**
- * Returns the curve point right after the given ap
- */
-AutomationCurve *
-automation_track_get_next_curve_ac (
- AutomationTrack * at,
- AutomationPoint * ap);
+automation_track_set_automatable (
+ AutomationTrack * automation_track,
+ Automatable * a);
/**
- * Removes automation point from automation track.
+ * Clones the AutomationTrack.
*/
-void
-automation_track_remove_ap (
- AutomationTrack * at,
- AutomationPoint * ap,
- int free);
+AutomationTrack *
+automation_track_clone (
+ AutomationTrack * src);
/**
- * Removes automation curve from automation track.
+ * Frees the automation track.
*/
void
-automation_track_remove_ac (
- AutomationTrack * at,
- AutomationCurve * ac);
-
-//int
-//automation_track_get_ap_index (AutomationTrack * at,
- //AutomationPoint * ap);
-
-//int
-//automation_track_get_curve_index (AutomationTrack * at,
- //AutomationCurve * ac);
+automation_track_free (AutomationTrack * at);
/**
* Returns the automation curve at the given pos.
@@ -248,8 +163,17 @@ automation_track_get_ac_at_pos (
*/
AutomationPoint *
automation_track_get_ap_before_pos (
- AutomationTrack * self,
- Position * pos);
+ const AutomationTrack * self,
+ const Position * pos);
+
+/**
+ * Returns the last Region before the given
+ * Position.
+ */
+Region *
+automation_track_get_region_before_pos (
+ const AutomationTrack * self,
+ const Position * pos);
/**
* Returns the actual parameter value at the given
@@ -270,4 +194,11 @@ automation_track_get_normalized_val_at_pos (
//void
//automation_track_update (AutomationTrack * at);
+/**
+ * Gets the last Region in the AutomationTrack.
+ */
+Region *
+automation_track_get_last_region (
+ AutomationTrack * self);
+
#endif // __AUDIO_AUTOMATION_TRACK_H__
diff --git a/inc/audio/chord_object.h b/inc/audio/chord_object.h
index a121496..045e9bf 100644
--- a/inc/audio/chord_object.h
+++ b/inc/audio/chord_object.h
@@ -73,22 +73,23 @@ typedef struct ChordObject
{
/** ChordObject object position (if used in chord
* Track). */
- Position pos;
+ Position pos;
/** Cache, used in runtime operations. */
- Position cache_pos;
+ Position cache_pos;
- ChordDescriptor * descr;
+ ChordDescriptor * descr;
- /** Position of Track this ChordObject is in. */
- int track_pos;
+ /** Pointer back to parent. */
+ Region * region;
- /** Cache. */
- Track * track;
+ /** Used in clones to identify a region instead of
+ * cloning the whole Region. */
+ char * region_name;
- ChordObjectWidget * widget;
+ ChordObjectWidget * widget;
- ArrangerObjectInfo obj_info;
+ ArrangerObjectInfo obj_info;
} ChordObject;
static const cyaml_schema_field_t
@@ -137,19 +138,12 @@ chord_object_is_equal (
}
/**
- * Returns the Track this ChordObject is in.
- */
-Track *
-chord_object_get_track (
- ChordObject * self);
-
-/**
* Sets the Track of the chord.
*/
void
-chord_object_set_track (
+chord_object_set_region (
ChordObject * self,
- Track * track);
+ Region * region);
/**
* Finds the ChordObject in the project
diff --git a/inc/audio/chord_region.h b/inc/audio/chord_region.h
new file mode 100644
index 0000000..a7cf18a
--- /dev/null
+++ b/inc/audio/chord_region.h
@@ -0,0 +1,84 @@
+/*
+ * Copyright (C) 2019 Alexandros Theodotou <alex at zrythm dot org>
+ *
+ * This file is part of Zrythm
+ *
+ * Zrythm is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Zrythm 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 Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with Zrythm. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+/**
+ * \file
+ *
+ * Region for ChordObject's.
+ */
+
+#ifndef __AUDIO_CHORD_REGION_H__
+#define __AUDIO_CHORD_REGION_H__
+
+typedef struct Position Position;
+typedef struct ChordObject ChordObject;
+typedef struct Region Region;
+
+/**
+ * @addtogroup audio
+ *
+ * @{
+ */
+
+/**
+ * Creates a new Region for chords.
+ *
+ * @param is_main If this is 1 it
+ * will create the additional Region (
+ * main_transient).
+ */
+Region *
+chord_region_new (
+ const Position * start_pos,
+ const Position * end_pos,
+ const int is_main);
+
+/**
+ * Adds a ChordObject to the Region.
+ */
+void
+chord_region_add_chord_object (
+ Region * self,
+ ChordObject * chord);
+
+/**
+ * Removes a ChordObject from the Region.
+ *
+ * @param free Optionally free the ChordObject.
+ */
+void
+chord_region_remove_chord_object (
+ Region * self,
+ ChordObject * chord,
+ int free);
+
+/**
+ * Frees members only but not the Region itself.
+ *
+ * Regions should be free'd using region_free.
+ */
+void
+chord_region_free_members (
+ Region * self);
+
+/**
+ * @}
+ */
+
+#endif
diff --git a/inc/audio/chord_track.h b/inc/audio/chord_track.h
index 4380f6f..b8e42ef 100644
--- a/inc/audio/chord_track.h
+++ b/inc/audio/chord_track.h
@@ -58,30 +58,9 @@ chord_track_new ();
* @param gen_widget Create a widget for the chord.
*/
void
-chord_track_add_chord (
- ChordTrack * track,
- ChordObject * chord,
- int gen_widget);
-
-/**
- * Adds a ChordObject to the Track.
- *
- * @param gen_widget Create a widget for the chord.
- */
-void
chord_track_add_scale (
ChordTrack * track,
- ScaleObject * chord,
- int gen_widget);
-
-/**
- * Removes a chord from the chord Track.
- */
-void
-chord_track_remove_chord (
- ChordTrack * self,
- ChordObject * chord,
- int free);
+ ScaleObject * chord);
/**
* Removes a scale from the chord Track.
diff --git a/inc/audio/dir.h b/inc/audio/dir.h
index 9362604..f81f738 100644
--- a/inc/audio/dir.h
+++ b/inc/audio/dir.h
@@ -1,4 +1,21 @@
/**
+ * Copyright (C) 2019 Alexandros Theodotou <alex at zrythm dot org>
+ *
+ * This file is part of Zrythm
+ *
+ * Zrythm is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Zrythm 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 Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with Zrythm. If not, see <https://www.gnu.org/licenses/>.
+ *
* @dir inc/audio
*
* Audio processing related code.
diff --git a/inc/audio/marker_track.h b/inc/audio/marker_track.h
index 80f26ab..31305f5 100644
--- a/inc/audio/marker_track.h
+++ b/inc/audio/marker_track.h
@@ -58,8 +58,7 @@ marker_track_default ();
void
marker_track_add_marker (
MarkerTrack * self,
- Marker * marker,
- int gen_widget);
+ Marker * marker);
/**
* Removes a marker, optionally freeing it.
diff --git a/inc/audio/midi_region.h b/inc/audio/midi_region.h
index 92c70d6..4a491a2 100644
--- a/inc/audio/midi_region.h
+++ b/inc/audio/midi_region.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2019 Alexandros Theodotou
+ * Copyright (C) 2019 Alexandros Theodotou <alex at zrythm dot org>
*
* This file is part of Zrythm
*
@@ -52,21 +52,12 @@ midi_region_new (
int is_main);
/**
- * Creates region (used when loading projects).
- */
-MidiRegion *
-midi_region_get_or_create_blank (int id);
-
-/**
* Adds midi note to region
- *
- * @param gen_widget Generate a MidiNoteWidget.
*/
void
midi_region_add_midi_note (
MidiRegion * region,
- MidiNote * midi_note,
- int gen_widget);
+ MidiNote * midi_note);
/**
* Returns the midi note with the given pitch from the
@@ -75,8 +66,9 @@ midi_region_add_midi_note (
* Used when recording.
*/
MidiNote *
-midi_region_find_unended_note (MidiRegion * self,
- int pitch);
+midi_region_find_unended_note (
+ MidiRegion * self,
+ int pitch);
/**
* Prints the MidiNotes in the Region.
@@ -155,7 +147,8 @@ midi_region_remove_all_midi_notes (
* Regions should be free'd using region_free.
*/
void
-midi_region_free_members (MidiRegion * self);
+midi_region_free_members (
+ MidiRegion * self);
/**
* @}
diff --git a/inc/audio/region.h b/inc/audio/region.h
index 641bd4d..f17fdb2 100644
--- a/inc/audio/region.h
+++ b/inc/audio/region.h
@@ -25,6 +25,9 @@
#ifndef __AUDIO_REGION_H__
#define __AUDIO_REGION_H__
+#include "audio/automation_point.h"
+#include "audio/automation_curve.h"
+#include "audio/chord_object.h"
#include "audio/midi_note.h"
#include "audio/midi_region.h"
#include "audio/position.h"
@@ -59,7 +62,11 @@ typedef struct _AudioClipWidget AudioClipWidget;
arranger_object_info_is_main ( \
&r->obj_info)
-/** Gets the TrackLane counterpart of the Region. */
+/**
+ * Gets the TrackLane counterpart of the Region.
+ *
+ * Only applies to Regions that have lanes.
+ */
#define region_get_lane_region(r) \
((Region *) r->obj_info.lane)
@@ -67,8 +74,12 @@ typedef struct _AudioClipWidget AudioClipWidget;
#define region_get_main_region(r) \
((Region *) r->obj_info.main)
-/** Gets the TrackLane counterpart of the Region
- * (transient). */
+/**
+ * Gets the TrackLane counterpart of the Region
+ * (transient).
+ *
+ * Only applies to Regions that have lanes.
+ */
#define region_get_lane_trans_region(r) \
((Region *) r->obj_info.lane_trans)
@@ -79,13 +90,28 @@ typedef struct _AudioClipWidget AudioClipWidget;
/**
* Type of Region.
+ *
+ * Bitfield instead of plain enum so multiple
+ * values can be passed to some functions (eg to
+ * collect all Regions of the given types in a
+ * Track).
*/
typedef enum RegionType
{
- REGION_TYPE_MIDI,
- REGION_TYPE_AUDIO
+ REGION_TYPE_MIDI = 0x01,
+ REGION_TYPE_AUDIO = 0x02,
+ REGION_TYPE_AUTOMATION = 0x04,
+ REGION_TYPE_CHORD = 0x08,
} RegionType;
+static const cyaml_bitdef_t
+region_type_bitvals[] =
+{
+ { .name = "midi", .offset = 0, .bits = 1 },
+ { .name = "audio", .offset = 1, .bits = 1 },
+ { .name = "automation", .offset = 2, .bits = 1 },
+};
+
/**
* Flag do indicate how to clone the Region.
*/
@@ -206,8 +232,9 @@ typedef struct Region
/* ==== MIDI REGION ==== */
/** MIDI notes. */
- MidiNote * midi_notes[800];
+ MidiNote ** midi_notes;
int num_midi_notes;
+ int midi_notes_size;
/**
* Unended notes started in recording with MIDI NOTE ON
@@ -242,6 +269,46 @@ typedef struct Region
/* ==== AUDIO REGION END ==== */
+ /* ==== AUTOMATION REGION ==== */
+
+ /**
+ * The automation points.
+ *
+ * Must always stay sorted by position.
+ */
+ AutomationPoint ** aps;
+ int num_aps;
+ int aps_size;
+
+ /**
+ * The AutomationCurve's.
+ *
+ * Their size will always be aps_size - 1 (or 0 if
+ * there are no AutomationPoint's).
+ */
+ AutomationCurve ** acs;
+ int num_acs;
+
+ /**
+ * Pointer back to the AutomationTrack.
+ *
+ * This doesn't have to be serialized - during
+ * loading, you can traverse the AutomationTrack's
+ * automation Region's and set it.
+ */
+ AutomationTrack * at;
+
+ /* ==== AUTOMATION REGION END ==== */
+
+ /* ==== CHORD REGION ==== */
+
+ /** ChordObject's in this Region. */
+ ChordObject ** chord_objects;
+ int num_chord_objects;
+ int chord_objects_size;
+
+ /* ==== CHORD REGION END ==== */
+
/**
* Info on whether this Region is transient/lane
* and pointers to transient/lane equivalents.
@@ -249,13 +316,6 @@ typedef struct Region
ArrangerObjectInfo obj_info;
} Region;
-static const cyaml_strval_t
-region_type_strings[] =
-{
- { "Midi", REGION_TYPE_MIDI },
- { "Audio", REGION_TYPE_AUDIO },
-};
-
static const cyaml_schema_field_t
region_fields_schema[] =
{
@@ -263,10 +323,10 @@ static const cyaml_schema_field_t
"name", CYAML_FLAG_POINTER,
Region, name,
0, CYAML_UNLIMITED),
- CYAML_FIELD_ENUM (
+ CYAML_FIELD_BITFIELD (
"type", CYAML_FLAG_DEFAULT,
- Region, type, region_type_strings,
- CYAML_ARRAY_LEN (region_type_strings)),
+ Region, type, region_type_bitvals,
+ CYAML_ARRAY_LEN (region_type_bitvals)),
CYAML_FIELD_MAPPING (
"start_pos", CYAML_FLAG_DEFAULT,
Region, start_pos, position_fields_schema),
@@ -314,6 +374,14 @@ static const cyaml_schema_field_t
CYAML_FIELD_INT (
"lane_pos", CYAML_FLAG_DEFAULT,
Region, lane_pos),
+ CYAML_FIELD_SEQUENCE_COUNT (
+ "aps", CYAML_FLAG_DEFAULT,
+ Region, aps, num_aps,
+ &automation_point_schema, 0, CYAML_UNLIMITED),
+ CYAML_FIELD_SEQUENCE_COUNT (
+ "acs", CYAML_FLAG_DEFAULT,
+ Region, acs, num_acs,
+ &automation_curve_schema, 0, CYAML_UNLIMITED),
CYAML_FIELD_END
};
@@ -337,7 +405,6 @@ ARRANGER_OBJ_DECLARE_MOVABLE_W_LENGTH (
void
region_init (
Region * region,
- const RegionType type,
const Position * start_pos,
const Position * end_pos,
const int is_main);
@@ -424,10 +491,10 @@ region_get_loop_length_in_ticks (
*/
void
region_timeline_pos_to_local (
- Region * region,
- Position * timeline_pos,
- Position * local_pos,
- int normalize);
+ Region * region,
+ const Position * timeline_pos,
+ Position * local_pos,
+ int normalize);
/**
* Returns the Track this Region is in.
diff --git a/inc/audio/track.h b/inc/audio/track.h
index 5a25ca9..ebc3132 100644
--- a/inc/audio/track.h
+++ b/inc/audio/track.h
@@ -196,8 +196,9 @@ typedef struct Track
/* ==== INSTRUMENT & AUDIO TRACK ==== */
/** Lanes in this track containing Regions. */
- TrackLane * lanes[14];
+ TrackLane ** lanes;
int num_lanes;
+ int lanes_size;
/* ==== INSTRUMENT & AUDIO TRACK END ==== */
@@ -208,34 +209,42 @@ typedef struct Track
*
* Note: these must always be sorted by Position.
*/
- ChordObject * chords[600];
- int num_chords;
+ Region ** chord_regions;
+ int num_chord_regions;
+ int chord_regions_size;
/**
* ScaleObject's.
*
* Note: these must always be sorted by Position.
*/
- ScaleObject * scales[600];
+ ScaleObject ** scales;
int num_scales;
+ int scales_size;
/* ==== CHORD TRACK END ==== */
- /* ---- MARKER TRACK ---- */
- Marker * markers[100];
+ /* ==== MARKER TRACK ==== */
+
+ Marker ** markers;
int num_markers;
- /* ---- MARKER TRACK END ---- */
+ int markers_size;
+
+ /* ==== MARKER TRACK END ==== */
/* ==== CHANNEL TRACK ==== */
+
/** 1 Track has 0 or 1 Channel. */
Channel * channel;
+
/* ==== CHANNEL TRACK END ==== */
AutomationTracklist automation_tracklist;
/** Modulators for this Track. */
- Modulator * modulators[MAX_MODULATORS];
+ Modulator ** modulators;
int num_modulators;
+ int modulators_size;
/**
* Flag to tell the UI that this channel had
@@ -302,9 +311,9 @@ track_fields_schema[] =
Track, lanes, num_lanes,
&track_lane_schema, 0, CYAML_UNLIMITED),
CYAML_FIELD_SEQUENCE_COUNT (
- "chords", CYAML_FLAG_DEFAULT,
- Track, chords, num_chords,
- &chord_object_schema, 0, CYAML_UNLIMITED),
+ "chord_regions", CYAML_FLAG_DEFAULT,
+ Track, chord_regions, num_chord_regions,
+ &region_schema, 0, CYAML_UNLIMITED),
CYAML_FIELD_SEQUENCE_COUNT (
"scales", CYAML_FLAG_DEFAULT,
Track, scales, num_scales,
@@ -406,26 +415,27 @@ int
track_is_selected (Track * self);
/**
- * Adds a Region to the given lane of the track.
+ * Adds a Region to the given lane or
+ * AutomationTrack of the track.
*
* The Region must be the main region (see
* ArrangerObjectInfo).
*
+ * @param at The AutomationTrack of this Region, if
+ * automation region.
* @param lane_pos The position of the lane to add
- * to.
+ * to, if applicable.
* @param gen_name Generate a unique region name or
* not. This will be 0 if the caller already
* generated a unique name.
- * @param gen_widget Generate a RegionWidget for
- * the Region.
*/
void
track_add_region (
- Track * track,
- Region * region,
- int lane_pos,
- int gen_name,
- int gen_widget);
+ Track * track,
+ Region * region,
+ AutomationTrack * at,
+ int lane_pos,
+ int gen_name);
/**
* Removes the region from the track.
@@ -443,22 +453,16 @@ track_remove_region (
*/
Region *
track_get_region_at_pos (
- Track * track,
- Position * pos);
+ const Track * track,
+ const Position * pos);
/**
- * Returns the last region in the track, or NULL.
+ * Returns the last Region in the
+ * track, or NULL.
*/
Region *
track_get_last_region (
- Track * track);
-
-/**
- * Returns the last region in the track, or NULL.
- */
-AutomationPoint *
-track_get_last_automation_point (
- Track * track);
+ Track * track);
/**
* Wrapper.
@@ -467,7 +471,8 @@ void
track_setup (Track * track);
/**
- * Returns the automation tracklist if the track type has one,
+ * Returns the automation tracklist if the track
+ * type has one,
* or NULL if it doesn't (like chord tracks).
*/
AutomationTracklist *
diff --git a/inc/audio/track_lane.h b/inc/audio/track_lane.h
index 862f2ae..af5a589 100644
--- a/inc/audio/track_lane.h
+++ b/inc/audio/track_lane.h
@@ -66,8 +66,9 @@ typedef struct TrackLane
int solo;
/** Regions in this track. */
- Region * regions[MAX_REGIONS];
+ Region ** regions;
int num_regions;
+ int regions_size;
/** Pointer back to the owner Track. */
Track * track;
diff --git a/inc/dir.h b/inc/dir.h
index f217205..8d31b0f 100644
--- a/inc/dir.h
+++ b/inc/dir.h
@@ -1,3 +1,20 @@
/**
+ * Copyright (C) 2019 Alexandros Theodotou <alex at zrythm dot org>
+ *
+ * This file is part of Zrythm
+ *
+ * Zrythm is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Zrythm 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 Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with Zrythm. If not, see <https://www.gnu.org/licenses/>.
+ *
* @dir inc Include dir.
*/
diff --git a/inc/gui/backend/arranger_selections.h b/inc/gui/backend/arranger_selections.h
new file mode 100644
index 0000000..e1f0dc8
--- /dev/null
+++ b/inc/gui/backend/arranger_selections.h
@@ -0,0 +1,309 @@
+/*
+ * Copyright (C) 2019 Alexandros Theodotou <alex at zrythm dot org>
+ *
+ * This file is part of Zrythm
+ *
+ * Zrythm is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Zrythm 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 Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+/**
+ * \file
+ *
+ * Common data structures and functions for
+ * *ArrangerSelections.
+ */
+
+#ifndef __GUI_BACKEND_ARRANGER_SELECTIONS_H__
+#define __GUI_BACKEND_ARRANGER_SELECTIONS_H__
+
+/**
+ * @addtogroup gui_backend
+ *
+ * @{
+ */
+
+/**
+ * Inits the selections after loading a project.
+ */
+#define ARRANGER_SELECTIONS_DECLARE_INIT_LOADED( \
+ cc,sc) \
+ void \
+ sc##_selections_init_loaded ( \
+ cc##Selections * self)
+
+/**
+ * Clone the struct for copying, undoing, etc.
+ */
+#define ARRANGER_SELECTIONS_DECLARE_CLONE(cc,sc) \
+ cc##Selections * \
+ sc##_selections_clone ( \
+ cc##Selections * mas)
+
+/**
+ * Returns if there are any selections.
+ */
+#define ARRANGER_SELECTIONS_DECLARE_HAS_ANY(cc,sc) \
+ int \
+ sc##_selections_has_any ( \
+ cc##Selections * mas)
+
+/**
+ * Returns the position of the leftmost object.
+ *
+ * @param transient If 1, the transient objects are
+ * checked instead.
+ * @param pos The return value will be stored here.
+ * @param global Return global (timeline) Position,
+ * otherwise returns the local (from the start
+ * of the Region) Position.
+ */
+#define ARRANGER_SELECTIONS_DECLARE_GET_START_POS_W_GLOBAL( \
+ cc,sc) \
+ void \
+ sc##_selections_get_start_pos ( \
+ cc##Selections * mas, \
+ Position * pos, \
+ int transient, \
+ int global)
+
+/**
+ * Returns the position of the leftmost object.
+ *
+ * @param transient If 1, the transient objects are
+ * checked instead.
+ * @param pos The return value will be stored here.
+ */
+#define ARRANGER_SELECTIONS_DECLARE_GET_START_POS( \
+ cc,sc) \
+ void \
+ sc##_selections_get_start_pos ( \
+ cc##Selections * mas, \
+ Position * pos, \
+ int transient)
+
+/**
+ * Returns the position of the rightmost object.
+ *
+ * @param pos The return value will be stored here.
+ * @param transient If 1, the transient objects are
+ * checked instead.
+ * @param global Return global (timeline) Position,
+ * otherwise returns the local (from the start
+ * of the Region) Position.
+ */
+#define ARRANGER_SELECTIONS_DECLARE_GET_END_POS_W_GLOBAL( \
+ cc,sc) \
+ void \
+ sc##_selections_get_end_pos ( \
+ cc##Selections * mas, \
+ Position * pos, \
+ int transient, \
+ int global)
+
+/**
+ * Returns the position of the rightmost object.
+ *
+ * @param pos The return value will be stored here.
+ * @param transient If 1, the transient objects are
+ * checked instead.
+ */
+#define ARRANGER_SELECTIONS_DECLARE_GET_END_POS( \
+ cc,sc) \
+ void \
+ sc##_selections_get_end_pos ( \
+ cc##Selections * mas, \
+ Position * pos, \
+ int transient)
+
+/**
+ * Gets first object's widget.
+ *
+ * @param transient If 1, transient objects are
+ * checked instead.
+ */
+#define ARRANGER_SELECTIONS_DECLARE_GET_FIRST_OBJ( \
+ cc,sc) \
+ GtkWidget * \
+ sc##_selections_get_first_object ( \
+ cc##Selections * mas, \
+ int transient)
+
+/**
+ * Gets last object's widget.
+ *
+ * @param transient If 1, transient objects are
+ * checked instead.
+ */
+#define ARRANGER_SELECTIONS_DECLARE_GET_LAST_OBJ( \
+ cc,sc) \
+ GtkWidget * \
+ sc##_selections_get_last_object ( \
+ cc##Selections * mas, \
+ int transient)
+
+/**
+ * Pastes the given selections to the given Position.
+ */
+#define ARRANGER_SELECTIONS_DECLARE_PASTE_TO_POS( \
+ cc,sc) \
+ void \
+ sc##_selections_paste_to_pos ( \
+ cc##Selections * ts, \
+ Position * pos)
+
+/**
+ * Sets the cache Position's for each object in
+ * the selection.
+ *
+ * Used by the ArrangerWidget's.
+ */
+#define ARRANGER_SELECTIONS_DECLARE_SET_CACHE_POSES( \
+ cc,sc) \
+ void \
+ sc##_selections_set_cache_poses ( \
+ cc##Selections * mas)
+
+/**
+ * Moves the selections by the given
+ * amount of ticks.
+ *
+ * @param use_cached_pos Add the ticks to the cached
+ * Position's instead of the current Position's.
+ * @param ticks Ticks to add.
+ * @param update_flag ArrangerObjectUpdateFlag.
+ */
+#define ARRANGER_SELECTIONS_DECLARE_ADD_TICKS(cc,sc) \
+ void \
+ sc##_selections_add_ticks ( \
+ cc##Selections * mas, \
+ long ticks, \
+ int use_cached_pos, \
+ ArrangerObjectUpdateFlag update_flag)
+
+/**
+ * Clears selections.
+ */
+#define ARRANGER_SELECTIONS_DECLARE_CLEAR(cc,sc) \
+ void \
+ sc##_selections_clear ( \
+ cc##Selections * mas)
+
+/**
+ * Frees the selections.
+ */
+#define ARRANGER_SELECTIONS_DECLARE_FREE(cc,sc) \
+ void \
+ sc##_selections_free ( \
+ cc##Selections * self)
+
+/**
+ * Frees all the objects as well.
+ *
+ * To be used in actions where the selections are
+ * all clones.
+ */
+#define ARRANGER_SELECTIONS_DECLARE_FREE_FULL(cc,sc) \
+ void \
+ sc##_selections_free_full ( \
+ cc##Selections * self)
+
+/**
+ * Declares all of the above functions.
+ */
+#define ARRANGER_SELECTIONS_DECLARE_FUNCS(cc,sc) \
+ ARRANGER_SELECTIONS_DECLARE_INIT_LOADED (cc,sc); \
+ ARRANGER_SELECTIONS_DECLARE_CLONE (cc,sc); \
+ ARRANGER_SELECTIONS_DECLARE_HAS_ANY (cc,sc); \
+ ARRANGER_SELECTIONS_DECLARE_GET_START_POS_W_GLOBAL (\
+ cc,sc); \
+ ARRANGER_SELECTIONS_DECLARE_GET_END_POS_W_GLOBAL (cc,sc); \
+ ARRANGER_SELECTIONS_DECLARE_GET_FIRST_OBJ (cc,sc); \
+ ARRANGER_SELECTIONS_DECLARE_GET_LAST_OBJ (cc,sc); \
+ ARRANGER_SELECTIONS_DECLARE_PASTE_TO_POS (cc,sc); \
+ ARRANGER_SELECTIONS_DECLARE_SET_CACHE_POSES ( \
+ cc,sc); \
+ ARRANGER_SELECTIONS_DECLARE_ADD_TICKS (cc,sc); \
+ ARRANGER_SELECTIONS_DECLARE_CLEAR (cc,sc); \
+ ARRANGER_SELECTIONS_DECLARE_FREE (cc,sc); \
+ ARRANGER_SELECTIONS_DECLARE_FREE_FULL (cc,sc)
+
+#define ARRANGER_SELECTIONS_DECLARE_TIMELINE_FUNCS( \
+ cc,sc) \
+ ARRANGER_SELECTIONS_DECLARE_INIT_LOADED (cc,sc); \
+ ARRANGER_SELECTIONS_DECLARE_CLONE (cc,sc); \
+ ARRANGER_SELECTIONS_DECLARE_HAS_ANY (cc,sc); \
+ ARRANGER_SELECTIONS_DECLARE_GET_START_POS (cc,sc); \
+ ARRANGER_SELECTIONS_DECLARE_GET_END_POS (cc,sc); \
+ ARRANGER_SELECTIONS_DECLARE_GET_FIRST_OBJ (cc,sc); \
+ ARRANGER_SELECTIONS_DECLARE_GET_LAST_OBJ (cc,sc); \
+ ARRANGER_SELECTIONS_DECLARE_PASTE_TO_POS (cc,sc); \
+ ARRANGER_SELECTIONS_DECLARE_SET_CACHE_POSES ( \
+ cc,sc); \
+ ARRANGER_SELECTIONS_DECLARE_ADD_TICKS (cc,sc); \
+ ARRANGER_SELECTIONS_DECLARE_CLEAR (cc,sc); \
+ ARRANGER_SELECTIONS_DECLARE_FREE (cc,sc); \
+ ARRANGER_SELECTIONS_DECLARE_FREE_FULL (cc,sc)
+
+/**
+ * Adds the arranger object to the selections.
+ */
+#define ARRANGER_SELECTIONS_DECLARE_ADD_OBJ( \
+ cc,sc,obj_cc,obj_sc) \
+ void \
+ sc##_selections_add_##obj_sc ( \
+ cc##Selections * self, \
+ obj_cc * obj_sc)
+
+/**
+ * Returns if the arranger object is in the
+ * selections or not.
+ *
+ * The object must be the main object (see
+ * ArrangerObjectInfo).
+ */
+#define ARRANGER_SELECTIONS_DECLARE_CONTAINS_OBJ( \
+ cc,sc,obj_cc,obj_sc) \
+ int \
+ sc##_selections_contains_##obj_sc ( \
+ cc##Selections * self, \
+ obj_cc * obj_sc)
+
+/**
+ * Removes the arranger object from the selections.
+ */
+#define ARRANGER_SELECTIONS_DECLARE_REMOVE_OBJ( \
+ cc,sc,obj_cc,obj_sc) \
+ void \
+ sc##_selections_remove_##obj_sc ( \
+ cc##Selections * ts, \
+ obj_cc * obj_sc)
+
+/**
+ * Declares the above arranger object-related
+ * functions.
+ */
+#define ARRANGER_SELECTIONS_DECLARE_OBJ_FUNCS( \
+ cc,sc,obj_cc,obj_sc) \
+ ARRANGER_SELECTIONS_DECLARE_ADD_OBJ ( \
+ cc, sc, obj_cc, obj_sc); \
+ ARRANGER_SELECTIONS_DECLARE_CONTAINS_OBJ ( \
+ cc, sc, obj_cc, obj_sc); \
+ ARRANGER_SELECTIONS_DECLARE_REMOVE_OBJ ( \
+ cc, sc, obj_cc, obj_sc)
+
+/**
+* @}
+*/
+
+#endif
diff --git a/inc/gui/backend/automation_editor.h b/inc/gui/backend/automation_editor.h
new file mode 100644
index 0000000..4efb66d
--- /dev/null
+++ b/inc/gui/backend/automation_editor.h
@@ -0,0 +1,83 @@
+/*
+ * Copyright (C) 2019 Alexandros Theodotou <alex at zrythm dot org>
+ *
+ * This file is part of Zrythm
+ *
+ * Zrythm is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Zrythm 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 Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with Zrythm. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+/**
+ * \file
+ *
+ * Automation editor backend.
+ */
+
+#ifndef __GUI_BACKEND_AUTOMATION_EDITOR_H__
+#define __GUI_BACKEND_AUTOMATION_EDITOR_H__
+
+#include <cyaml/cyaml.h>
+
+/**
+ * @addtogroup gui_backend
+ *
+ * @{
+ */
+
+#define AUTOMATION_EDITOR \
+ (&CLIP_EDITOR->automation_editor)
+
+typedef struct Region Region;
+
+/**
+ * Backend for the automation editor.
+ */
+typedef struct AutomationEditor
+{
+} AutomationEditor;
+
+static const cyaml_schema_field_t
+automation_editor_fields_schema[] =
+{
+
+ CYAML_FIELD_END
+};
+
+static const cyaml_schema_value_t
+automation_editor_schema =
+{
+ CYAML_VALUE_MAPPING (
+ CYAML_FLAG_POINTER,
+ AutomationEditor, automation_editor_fields_schema),
+};
+
+/**
+ * Inits the AutomationEditor after a Project has been
+ * loaded.
+ */
+void
+automation_editor_init_loaded (
+ AutomationEditor * self);
+
+/**
+ * Initializes the AutomationEditor.
+ */
+void
+automation_editor_init (
+ AutomationEditor * self);
+
+/**
+ * @}
+ */
+
+#endif
diff --git a/inc/gui/backend/automation_selections.h b/inc/gui/backend/automation_selections.h
new file mode 100644
index 0000000..181a872
--- /dev/null
+++ b/inc/gui/backend/automation_selections.h
@@ -0,0 +1,94 @@
+/*
+ * Copyright (C) 2019 Alexandros Theodotou <alex at zrythm dot org>
+ *
+ * This file is part of Zrythm
+ *
+ * Zrythm is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Zrythm 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 Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+/**
+ * \file
+ *
+ * API for selections in the AutomationArrangerWidget.
+ */
+
+#ifndef __GUI_BACKEND_AUTOMATION_SELECTIONS_H__
+#define __GUI_BACKEND_AUTOMATION_SELECTIONS_H__
+
+#include "audio/automation_point.h"
+#include "gui/backend/arranger_selections.h"
+#include "utils/yaml.h"
+
+/**
+ * @addtogroup gui_backend
+ *
+ * @{
+ */
+
+#define AUTOMATION_SELECTIONS \
+ (&PROJECT->automation_selections)
+
+/**
+ * Selections to be used for the AutomationArrangerWidget's
+ * current selections, copying, undoing, etc.
+ */
+typedef struct AutomationSelections
+{
+ /** Selected AutomationObject's. */
+ AutomationPoint * automation_points[600];
+ int num_automation_points;
+
+} AutomationSelections;
+
+static const cyaml_schema_field_t
+ automation_selections_fields_schema[] =
+{
+ CYAML_FIELD_SEQUENCE_COUNT (
+ "automation_points", CYAML_FLAG_DEFAULT,
+ AutomationSelections, automation_points,
+ num_automation_points,
+ &automation_point_schema, 0, CYAML_UNLIMITED),
+
+ CYAML_FIELD_END
+};
+
+static const cyaml_schema_value_t
+automation_selections_schema = {
+ CYAML_VALUE_MAPPING (
+ CYAML_FLAG_POINTER,
+ AutomationSelections,
+ automation_selections_fields_schema),
+};
+
+ARRANGER_SELECTIONS_DECLARE_FUNCS (
+ Automation, automation);
+ARRANGER_SELECTIONS_DECLARE_OBJ_FUNCS (
+ Automation, automation, AutomationPoint,
+ automation_point);
+
+#define automation_selections_contains_ap \
+ automation_selections_contains_automation_point
+
+SERIALIZE_INC (AutomationSelections,
+ automation_selections)
+DESERIALIZE_INC (AutomationSelections,
+ automation_selections)
+PRINT_YAML_INC (AutomationSelections,
+ automation_selections)
+
+/**
+* @}
+*/
+
+#endif
diff --git a/inc/gui/backend/chord_editor.h b/inc/gui/backend/chord_editor.h
new file mode 100644
index 0000000..76343be
--- /dev/null
+++ b/inc/gui/backend/chord_editor.h
@@ -0,0 +1,83 @@
+/*
+ * Copyright (C) 2019 Alexandros Theodotou <alex at zrythm dot org>
+ *
+ * This file is part of Zrythm
+ *
+ * Zrythm is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Zrythm 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 Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with Zrythm. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+/**
+ * \file
+ *
+ * Chord editor backend.
+ */
+
+#ifndef __GUI_BACKEND_CHORD_EDITOR_H__
+#define __GUI_BACKEND_CHORD_EDITOR_H__
+
+#include <cyaml/cyaml.h>
+
+/**
+ * @addtogroup gui_backend
+ *
+ * @{
+ */
+
+#define CHORD_EDITOR \
+ (&CLIP_EDITOR->chord_editor)
+
+typedef struct Region Region;
+
+/**
+ * Backend for the chord editor.
+ */
+typedef struct ChordEditor
+{
+} ChordEditor;
+
+static const cyaml_schema_field_t
+chord_editor_fields_schema[] =
+{
+
+ CYAML_FIELD_END
+};
+
+static const cyaml_schema_value_t
+chord_editor_schema =
+{
+ CYAML_VALUE_MAPPING (
+ CYAML_FLAG_POINTER,
+ ChordEditor, chord_editor_fields_schema),
+};
+
+/**
+ * Inits the ChordEditor after a Project has been
+ * loaded.
+ */
+void
+chord_editor_init_loaded (
+ ChordEditor * self);
+
+/**
+ * Initializes the ChordEditor.
+ */
+void
+chord_editor_init (
+ ChordEditor * self);
+
+/**
+ * @}
+ */
+
+#endif
diff --git a/inc/gui/backend/chord_selections.h b/inc/gui/backend/chord_selections.h
new file mode 100644
index 0000000..c1a25f2
--- /dev/null
+++ b/inc/gui/backend/chord_selections.h
@@ -0,0 +1,89 @@
+/*
+ * Copyright (C) 2019 Alexandros Theodotou <alex at zrythm dot org>
+ *
+ * This file is part of Zrythm
+ *
+ * Zrythm is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Zrythm 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 Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+/**
+ * \file
+ *
+ * API for selections in the piano roll.
+ */
+
+#ifndef __GUI_BACKEND_CHORD_SELECTIONS_H__
+#define __GUI_BACKEND_CHORD_SELECTIONS_H__
+
+#include "audio/chord_object.h"
+#include "gui/backend/arranger_selections.h"
+#include "utils/yaml.h"
+
+/**
+ * @addtogroup gui_backend
+ *
+ * @{
+ */
+
+#define CHORD_SELECTIONS \
+ (&PROJECT->chord_selections)
+
+/**
+ * Selections to be used for the ChordArrangerWidget's
+ * current selections, copying, undoing, etc.
+ */
+typedef struct ChordSelections
+{
+ /** Selected ChordObject's. */
+ ChordObject * chord_objects[600];
+ int num_chord_objects;
+
+} ChordSelections;
+
+static const cyaml_schema_field_t
+ chord_selections_fields_schema[] =
+{
+ CYAML_FIELD_SEQUENCE_COUNT (
+ "chord_objects", CYAML_FLAG_DEFAULT,
+ ChordSelections, chord_objects, num_chord_objects,
+ &chord_object_schema, 0, CYAML_UNLIMITED),
+
+ CYAML_FIELD_END
+};
+
+static const cyaml_schema_value_t
+chord_selections_schema = {
+ CYAML_VALUE_MAPPING (
+ CYAML_FLAG_POINTER,
+ ChordSelections,
+ chord_selections_fields_schema),
+};
+
+ARRANGER_SELECTIONS_DECLARE_FUNCS (
+ Chord, chord);
+ARRANGER_SELECTIONS_DECLARE_OBJ_FUNCS (
+ Chord, chord, ChordObject, chord_object);
+
+SERIALIZE_INC (ChordSelections,
+ chord_selections)
+DESERIALIZE_INC (ChordSelections,
+ chord_selections)
+PRINT_YAML_INC (ChordSelections,
+ chord_selections)
+
+/**
+* @}
+*/
+
+#endif
diff --git a/inc/gui/backend/clip_editor.h b/inc/gui/backend/clip_editor.h
index 5ae2673..f8c89b1 100644
--- a/inc/gui/backend/clip_editor.h
+++ b/inc/gui/backend/clip_editor.h
@@ -23,11 +23,13 @@
* The clip/region editor backend.
*/
-#ifndef __AUDIO_CLIP_EDITOR_H__
-#define __AUDIO_CLIP_EDITOR_H__
+#ifndef __GUI_BACKEND_CLIP_EDITOR_H__
+#define __GUI_BACKEND_CLIP_EDITOR_H__
-#include "gui/backend/piano_roll.h"
#include "gui/backend/audio_clip_editor.h"
+#include "gui/backend/automation_editor.h"
+#include "gui/backend/chord_editor.h"
+#include "gui/backend/piano_roll.h"
/**
* @addtogroup gui_backend
@@ -41,9 +43,10 @@
typedef struct Region Region;
/**
- * Piano roll serializable backend.
+ * Clip editor serializable backend.
*
- * The actual widgets should reflect the information here.
+ * The actual widgets should reflect the
+ * information here.
*/
typedef struct ClipEditor
{
@@ -54,6 +57,8 @@ typedef struct ClipEditor
PianoRoll piano_roll;
AudioClipEditor audio_clip_editor;
+ AutomationEditor automation_editor;
+ ChordEditor chord_editor;
/** Flag used by rulers when region first
* changes. */
@@ -72,6 +77,14 @@ clip_editor_fields_schema[] =
"piano_roll", CYAML_FLAG_DEFAULT,
ClipEditor, piano_roll,
piano_roll_fields_schema),
+ CYAML_FIELD_MAPPING (
+ "automation_editor", CYAML_FLAG_DEFAULT,
+ ClipEditor, automation_editor,
+ automation_editor_fields_schema),
+ CYAML_FIELD_MAPPING (
+ "chord_editor", CYAML_FLAG_DEFAULT,
+ ClipEditor, chord_editor,
+ chord_editor_fields_schema),
CYAML_FIELD_END
};
@@ -101,7 +114,8 @@ clip_editor_init (
* To be called only from GTK threads.
*/
void
-clip_editor_set_region (Region * region);
+clip_editor_set_region (
+ Region * region);
/**
* @}
diff --git a/inc/gui/backend/dir.h b/inc/gui/backend/dir.h
index 96d8a52..2f95b43 100644
--- a/inc/gui/backend/dir.h
+++ b/inc/gui/backend/dir.h
@@ -1,3 +1,22 @@
+/*
+ * Copyright (C) 2019 Alexandros Theodotou <alex at zrythm dot org>
+ *
+ * This file is part of Zrythm
+ *
+ * Zrythm is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Zrythm 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 Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with Zrythm. If not, see <https://www.gnu.org/licenses/>.
+ */
+
/**
* @dir inc/gui/backend
*
diff --git a/inc/gui/backend/events.h b/inc/gui/backend/events.h
index d5043c7..9b118f2 100644
--- a/inc/gui/backend/events.h
+++ b/inc/gui/backend/events.h
@@ -168,6 +168,10 @@ typedef enum EventType
ET_PIANO_ROLL_MIDI_MODIFIER_CHANGED,
ET_TIMELINE_OBJECTS_IN_TRANSIT,
ET_AUTOMATION_TRACKLIST_AT_REMOVED,
+ ET_CHORD_OBJECTS_IN_TRANSIT,
+ ET_CHORD_SELECTIONS_CHANGED,
+ ET_AUTOMATION_OBJECTS_IN_TRANSIT,
+ ET_AUTOMATION_SELECTIONS_CHANGED,
} EventType;
/**
diff --git a/inc/gui/backend/midi_arranger_selections.h b/inc/gui/backend/midi_arranger_selections.h
index 9be44be..21c1fd0 100644
--- a/inc/gui/backend/midi_arranger_selections.h
+++ b/inc/gui/backend/midi_arranger_selections.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2019 Alexandros Theodotou
+ * Copyright (C) 2019 Alexandros Theodotou <alex at zrythm dot org>
*
* This file is part of Zrythm
*
@@ -23,10 +23,11 @@
* API for selections in the piano roll.
*/
-#ifndef __ACTIONS_MA_SELECTIONS_H__
-#define __ACTIONS_MA_SELECTIONS_H__
+#ifndef __GUI_BACKEND_MA_SELECTIONS_H__
+#define __GUI_BACKEND_MA_SELECTIONS_H__
#include "audio/midi_note.h"
+#include "gui/backend/arranger_selections.h"
#include "utils/yaml.h"
/**
@@ -63,82 +64,16 @@ static const cyaml_schema_field_t
static const cyaml_schema_value_t
midi_arranger_selections_schema = {
- CYAML_VALUE_MAPPING(CYAML_FLAG_POINTER,
- MidiArrangerSelections, midi_arranger_selections_fields_schema),
+ CYAML_VALUE_MAPPING (
+ CYAML_FLAG_POINTER,
+ MidiArrangerSelections,
+ midi_arranger_selections_fields_schema),
};
-void
-midi_arranger_selections_init_loaded (
- MidiArrangerSelections * self);
-
-/**
- * Clone the struct for copying, undoing, etc.
- */
-MidiArrangerSelections *
-midi_arranger_selections_clone (
- MidiArrangerSelections * mas);
-
-/**
- * Returns if there are any selections.
- */
-int
-midi_arranger_selections_has_any (
- MidiArrangerSelections * mas);
-
-/**
- * Returns the position of the leftmost object.
- *
- * If transient is 1, the transient objects are
- * checked instead.
- *
- * The return value will be stored in pos.
- *
- * @param global Return global (timeline) Position,
- * otherwise returns the local (from the start
- * of the Region) Position.
- */
-void
-midi_arranger_selections_get_start_pos (
- MidiArrangerSelections * mas,
- Position * pos,
- int transient,
- int global);
-
-/**
- * Returns the position of the rightmost object.
- *
- * If transient is 1, the transient objects are
- * checked instead.
- *
- * The return value will be stored in pos.
- */
-void
-midi_arranger_selections_get_end_pos (
- MidiArrangerSelections * mas,
- Position * pos,
- int transient);
-
-/**
- * Gets first object's widget.
- *
- * If transient is 1, transient objects are checked
- * instead.
- */
-GtkWidget *
-midi_arranger_selections_get_first_object (
- MidiArrangerSelections * mas,
- int transient);
-
-/**
- * Gets last object's widget.
- *
- * If transient is 1, transient objects are checked
- * instead.
- */
-GtkWidget *
-midi_arranger_selections_get_last_object (
- MidiArrangerSelections * mas,
- int transient);
+ARRANGER_SELECTIONS_DECLARE_FUNCS (
+ MidiArranger, midi_arranger);
+ARRANGER_SELECTIONS_DECLARE_OBJ_FUNCS (
+ MidiArranger, midi_arranger, MidiNote, midi_note);
/**
* Gets first (position-wise) MidiNote.
@@ -172,27 +107,6 @@ midi_arranger_selections_get_lowest_note (
MidiArrangerSelections * mas,
int transient);
-void
-midi_arranger_selections_paste_to_pos (
- MidiArrangerSelections * ts,
- Position * pos);
-
-/**
- * Only removes transients from their regions and
- * frees them.
- */
-void
-midi_arranger_selections_remove_transients (
- MidiArrangerSelections * mas);
-
-/**
- * Adds a note to the selections.
- */
-void
-midi_arranger_selections_add_midi_note (
- MidiArrangerSelections * mas,
- MidiNote * note);
-
/**
* Adds a Velocity (MidiNote) to the selections.
*/
@@ -202,14 +116,6 @@ midi_arranger_selections_add_midi_note (
mas, vel->midi_note)
/**
- * Removes a MidiNote from the selections.
- */
-void
-midi_arranger_selections_remove_midi_note (
- MidiArrangerSelections * mas,
- MidiNote * note);
-
-/**
* Removes a Velocity (MidiNote) from the
* selections.
*/
@@ -218,55 +124,6 @@ midi_arranger_selections_remove_midi_note (
midi_arranger_selections_remove_midi_note ( \
mas, vel->midi_note)
-/**
- * Sets the cache Position's for each object in
- * the selection.
- *
- * Used by the ArrangerWidget's.
- */
-void
-midi_arranger_selections_set_cache_poses (
- MidiArrangerSelections * mas);
-
-/**
- * Returns if the MidiArrangerSelections contain
- * the given MidiNote.
- *
- * The note must be the main note (see
- * midi_note_get_main_midi_note()).
- */
-int
-midi_arranger_selections_contains_midi_note (
- MidiArrangerSelections * mas,
- MidiNote * note);
-
-/**
- * Moves the MidiArrangerSelections by the given
- * amount of ticks.
- *
- * @param use_cached_pos Add the ticks to the cached
- * Position's instead of the current Position's.
- * @param ticks Ticks to add.
- * @param update_flag ArrangerObjectUpdateFlag.
- */
-void
-midi_arranger_selections_add_ticks (
- MidiArrangerSelections * mas,
- long ticks,
- int use_cached_pos,
- ArrangerObjectUpdateFlag update_flag);
-
-/**
- * Clears selections.
- */
-void
-midi_arranger_selections_clear (
- MidiArrangerSelections * mas);
-
-void
-midi_arranger_selections_free (
- MidiArrangerSelections * self);
-
SERIALIZE_INC (MidiArrangerSelections,
midi_arranger_selections)
DESERIALIZE_INC (MidiArrangerSelections,
diff --git a/inc/gui/backend/piano_roll.h b/inc/gui/backend/piano_roll.h
index 9b094f4..9b4899d 100644
--- a/inc/gui/backend/piano_roll.h
+++ b/inc/gui/backend/piano_roll.h
@@ -23,8 +23,8 @@
* Piano roll backend.
*/
-#ifndef __AUDIO_PIANO_ROLL_H__
-#define __AUDIO_PIANO_ROLL_H__
+#ifndef __GUI_BACKEND_PIANO_ROLL_H__
+#define __GUI_BACKEND_PIANO_ROLL_H__
#include <cyaml/cyaml.h>
diff --git a/inc/gui/backend/timeline_selections.h b/inc/gui/backend/timeline_selections.h
index d01e84e..31ffd64 100644
--- a/inc/gui/backend/timeline_selections.h
+++ b/inc/gui/backend/timeline_selections.h
@@ -26,12 +26,11 @@
#ifndef __GUI_BACKEND_TL_SELECTIONS_H__
#define __GUI_BACKEND_TL_SELECTIONS_H__
-#include "audio/automation_point.h"
-#include "audio/chord_object.h"
#include "audio/marker.h"
#include "audio/midi_region.h"
#include "audio/region.h"
#include "audio/scale_object.h"
+#include "gui/backend/arranger_selections.h"
#include "utils/yaml.h"
/**
@@ -53,14 +52,6 @@ typedef struct TimelineSelections
Region * regions[600];
int num_regions;
- /** Selected AutomationPoint's. */
- AutomationPoint * automation_points[600];
- int num_automation_points;
-
- /** Selected ChordObject's. */
- ChordObject * chord_objects[800];
- int num_chord_objects;
-
/** Selected ScaleObject's. */
ScaleObject * scale_objects[800];
int num_scale_objects;
@@ -78,15 +69,14 @@ static const cyaml_schema_field_t
TimelineSelections, regions, num_regions,
&region_schema, 0, CYAML_UNLIMITED),
CYAML_FIELD_SEQUENCE_COUNT (
- "aps", CYAML_FLAG_DEFAULT,
- TimelineSelections, automation_points,
- num_automation_points,
- &automation_point_schema, 0, CYAML_UNLIMITED),
+ "scale_objects", CYAML_FLAG_DEFAULT,
+ TimelineSelections, scale_objects,
+ num_scale_objects,
+ &scale_object_schema, 0, CYAML_UNLIMITED),
CYAML_FIELD_SEQUENCE_COUNT (
- "chords", CYAML_FLAG_DEFAULT,
- TimelineSelections, chord_objects,
- num_chord_objects,
- &chord_object_schema, 0, CYAML_UNLIMITED),
+ "markers", CYAML_FLAG_DEFAULT,
+ TimelineSelections, markers, num_markers,
+ &marker_schema, 0, CYAML_UNLIMITED),
CYAML_FIELD_END
};
@@ -98,72 +88,14 @@ timeline_selections_schema = {
timeline_selections_fields_schema),
};
-void
-timeline_selections_init_loaded (
- TimelineSelections * ts);
-
-/**
- * Clone the struct for copying, undoing, etc.
- */
-TimelineSelections *
-timeline_selections_clone ();
-
-/**
- * Returns if there are any selections.
- */
-int
-timeline_selections_has_any (
- TimelineSelections * ts);
-
-/**
- * Returns the position of the leftmost object.
- *
- * If transient is 1, the transient objects are
- * checked instead.
- *
- * The return value will be stored in pos.
- */
-void
-timeline_selections_get_start_pos (
- TimelineSelections * ts,
- Position * pos,
- int transient);
-
-/**
- * Returns the position of the rightmost object.
- *
- * If transient is 1, the transient objects are
- * checked instead.
- *
- * The return value will be stored in pos.
- */
-void
-timeline_selections_get_end_pos (
- TimelineSelections * ts,
- Position * pos,
- int transient);
-
-/**
- * Gets first object's widget.
- *
- * If transient is 1, transient objects rae checked
- * instead.
- */
-GtkWidget *
-timeline_selections_get_first_object (
- TimelineSelections * ts,
- int transient);
-
-/**
- * Gets last object's widget.
- *
- * If transient is 1, transient objects rae checked
- * instead.
- */
-GtkWidget *
-timeline_selections_get_last_object (
- TimelineSelections * ts,
- int transient);
+ARRANGER_SELECTIONS_DECLARE_TIMELINE_FUNCS (
+ Timeline, timeline);
+ARRANGER_SELECTIONS_DECLARE_OBJ_FUNCS (
+ Timeline, timeline, Region, region);
+ARRANGER_SELECTIONS_DECLARE_OBJ_FUNCS (
+ Timeline, timeline, ScaleObject, scale_object);
+ARRANGER_SELECTIONS_DECLARE_OBJ_FUNCS (
+ Timeline, timeline, Marker, marker);
/**
* Gets highest track in the selections.
@@ -187,76 +119,6 @@ timeline_selections_get_lowest_track (
TimelineSelections * ts,
int transient);
-void
-timeline_selections_paste_to_pos (
- TimelineSelections * ts,
- Position * pos);
-
-/**
- * Returns if the timeline object is in the
- * selections or not.
- */
-#define CONTAINS_FUNC_DECL(cc,sc) \
- int \
- timeline_selections_contains_##sc ( \
- TimelineSelections * self, \
- cc * sc)
-
-CONTAINS_FUNC_DECL (Region, region);
-CONTAINS_FUNC_DECL (ChordObject, chord_object);
-CONTAINS_FUNC_DECL (ScaleObject, scale_object);
-CONTAINS_FUNC_DECL (Marker, marker);
-CONTAINS_FUNC_DECL (
- AutomationPoint, automation_point);
-
-#undef CONTAINS_FUNC_DECL
-
-/**
- * Adds the timeline object to the selections.
- */
-#define ADD_FUNC_DECL(cc,sc) \
- void \
- timeline_selections_add_##sc ( \
- TimelineSelections * ts, \
- cc * sc)
-
-ADD_FUNC_DECL (Region, region);
-ADD_FUNC_DECL (ChordObject, chord_object);
-ADD_FUNC_DECL (ScaleObject, scale_object);
-ADD_FUNC_DECL (Marker, marker);
-ADD_FUNC_DECL (
- AutomationPoint, automation_point);
-
-#undef ADD_FUNC_DECL
-
-/**
- * Removes a timeline object from the selections.
- */
-#define REMOVE_FUNC_DECL(cc,sc) \
- void \
- timeline_selections_remove_##sc ( \
- TimelineSelections * ts, \
- cc * sc)
-
-REMOVE_FUNC_DECL (Region, region);
-REMOVE_FUNC_DECL (ChordObject, chord_object);
-REMOVE_FUNC_DECL (ScaleObject, scale_object);
-REMOVE_FUNC_DECL (Marker, marker);
-REMOVE_FUNC_DECL (
- AutomationPoint, automation_point);
-
-#undef REMOVE_FUNC_DECL
-
-/**
- * Sets the cache Position's for each object in
- * the selection.
- *
- * Used by the ArrangerWidget's.
- */
-void
-timeline_selections_set_cache_poses (
- TimelineSelections * ts);
-
/**
* Set all transient Position's to their main
* counterparts.
@@ -282,32 +144,6 @@ void
timeline_selections_set_to_transient_values (
TimelineSelections * ts);
-/**
- * Moves the TimelineSelections by the given
- * amount of ticks.
- *
- * @param use_cached_pos Add the ticks to the cached
- * Position's instead of the current Position's.
- * @param ticks Ticks to add.
- * @param update_flag ArrangerObjectUpdateFlag.
- */
-void
-timeline_selections_add_ticks (
- TimelineSelections * ts,
- long ticks,
- int use_cached_pos,
- ArrangerObjectUpdateFlag update_flag);
-
-/**
- * Clears selections.
- */
-void
-timeline_selections_clear (
- TimelineSelections * ts);
-
-void
-timeline_selections_free (TimelineSelections * self);
-
SERIALIZE_INC (
TimelineSelections, timeline_selections)
DESERIALIZE_INC (
diff --git a/inc/gui/dir.h b/inc/gui/dir.h
index eb1f7e5..3d6aa73 100644
--- a/inc/gui/dir.h
+++ b/inc/gui/dir.h
@@ -1,5 +1,24 @@
+/*
+ * Copyright (C) 2019 Alexandros Theodotou <alex at zrythm dot org>
+ *
+ * This file is part of Zrythm
+ *
+ * Zrythm is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Zrythm 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 Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with Zrythm. If not, see <https://www.gnu.org/licenses/>.
+ */
+
/**
- * @dir inc/gui
+ * @dir inc/gui
*
* GUI-specific code.
*
diff --git a/inc/gui/widgets/arranger.h b/inc/gui/widgets/arranger.h
index 74f29da..fbc3031 100644
--- a/inc/gui/widgets/arranger.h
+++ b/inc/gui/widgets/arranger.h
@@ -249,6 +249,189 @@ typedef struct _ArrangerWidgetClass
} ArrangerWidgetClass;
/**
+ * Declares the get hit function.
+ */
+#define ARRANGER_W_DECLARE_GET_HIT_WIDGET( \
+ arr_name_cc,arr_name_sc,cc,sc) \
+ cc##Widget * \
+ arr_name_sc##_arranger_widget_get_hit_##sc ( \
+ arr_name_cc##ArrangerWidget * self, \
+ double x, \
+ double y)
+
+/**
+ * Declares the drag begin hit function.
+ */
+#define ARRANGER_W_DECLARE_ON_DRAG_BEGIN_X_HIT( \
+ arr_name_cc,arr_name_sc,cc,sc) \
+ void \
+ arr_name_sc##_arranger_widget_on_drag_begin_##sc##_hit ( \
+ arr_name_cc##ArrangerWidget * self, \
+ double start_x, \
+ cc##Widget * hit_w)
+
+/**
+ * Sets up an arranger object by declaring the
+ * following functions:
+ * - get hit
+ * - on drag begin hit
+ */
+#define ARRANGER_W_DECLARE_CHILD_OBJ_FUNCS( \
+ arr_name_cc,arr_name_sc,cc,sc) \
+ARRANGER_W_DECLARE_GET_HIT_WIDGET ( \
+ arr_name_cc, arr_name_sc, cc, sc); \
+ARRANGER_W_DECLARE_ON_DRAG_BEGIN_X_HIT ( \
+ arr_name_cc, arr_name_sc, cc, sc)
+
+/**
+ * Selects all objects.
+ */
+#define ARRANGER_W_DECLARE_SELECT_ALL(cc,sc) \
+ void \
+ sc##_arranger_widget_select_all ( \
+ cc##ArrangerWidget * self, \
+ int select)
+
+/** Called from get_child_position to allocate
+ * the overlay children */
+#define ARRANGER_W_DECLARE_SET_ALLOCATION(cc,sc) \
+ void \
+ sc##_arranger_widget_set_allocation ( \
+ cc##ArrangerWidget * self, \
+ GtkWidget * widget, \
+ GdkRectangle * allocation)
+
+/**
+ * Sets transient object and actual object
+ * visibility based on the current action.
+ */
+#define ARRANGER_W_DECLARE_UPDATE_VISIBILITY( \
+ cc,sc) \
+ void \
+ sc##_arranger_widget_update_visibility ( \
+ cc##ArrangerWidget * self)
+
+/**
+ * Returns the appropriate cursor based on the
+ * current hover_x and y.
+ */
+#define ARRANGER_W_DECLARE_GET_CURSOR(cc,sc) \
+ ArrangerCursor \
+ sc##_arranger_widget_get_cursor ( \
+ cc##ArrangerWidget * self, \
+ UiOverlayAction action, \
+ Tool tool)
+
+/**
+ * Moves the corresponding selections by the given
+ * amount of ticks.
+ *
+ * @param ticks_diff Ticks to move by.
+ * @param copy_moving 1 if copy-moving.
+ */
+#define ARRANGER_W_DECLARE_MOVE_ITEMS_X(cc,sc) \
+ void \
+ sc##_arranger_widget_move_items_x ( \
+ cc##ArrangerWidget * self, \
+ long ticks_diff, \
+ int copy_moving)
+
+/**
+ * Called when moving selected items in
+ * drag update for moving up/down (changing Track
+ * of a Region, changing MidiNote pitch, etc.).
+ */
+#define ARRANGER_W_DECLARE_MOVE_ITEMS_Y(cc,sc) \
+ void \
+ sc##_arranger_widget_move_items_y ( \
+ cc##ArrangerWidget *self, \
+ double offset_y)
+
+/**
+ * Readd children.
+ */
+#define ARRANGER_W_DECLARE_REFRESH_CHILDREN(cc,sc) \
+ void \
+ sc##_arranger_widget_refresh_children ( \
+ cc##ArrangerWidget * self)
+
+/**
+ * To be called once at init time to set up the
+ * arranger.
+ */
+#define ARRANGER_W_DECLARE_SETUP(cc,sc) \
+ void \
+ sc##_arranger_widget_setup ( \
+ cc##ArrangerWidget * self)
+
+/**
+ * Called by an arranger widget during drag_update
+ * to find and select (or delete) child objects
+ * enclosed in the selection area.
+ *
+ * @param delete If this is a select-delete
+ * operation
+ */
+#define ARRANGER_W_DECLARE_SELECT(cc,sc) \
+ void \
+ sc##_arranger_widget_select ( \
+ cc##ArrangerWidget * self, \
+ const double offset_x, \
+ const double offset_y, \
+ const int delete)
+
+/**
+ * Shows context menu.
+ *
+ * To be called from parent on right click.
+ */
+#define ARRANGER_W_DECLARE_SHOW_CONTEXT_MENU( \
+ cc,sc) \
+ void \
+ sc##_arranger_widget_show_context_menu ( \
+ cc##ArrangerWidget * self, \
+ gdouble x, \
+ gdouble y)
+
+/**
+ * Called on drag end to set default cursors back,
+ * clear any start* variables, call actions, etc.
+ */
+#define ARRANGER_W_DECLARE_ON_DRAG_END(cc,sc) \
+ void \
+ sc##_arranger_widget_on_drag_end ( \
+ cc##ArrangerWidget * self)
+
+/**
+ * Sets width to ruler width and height to the
+ * corresponding height, if any (eg Tracklist
+ * height for TimelineArrangerWidget).
+ */
+#define ARRANGER_W_DECLARE_SET_SIZE(cc,sc) \
+ void \
+ sc##_arranger_widget_set_size ( \
+ cc##ArrangerWidget * self)
+
+/**
+ * Declares all functions that an arranger must
+ * have.
+ */
+#define ARRANGER_W_DECLARE_FUNCS( \
+ cc,sc) \
+ ARRANGER_W_DECLARE_SELECT_ALL (cc, sc); \
+ ARRANGER_W_DECLARE_SET_ALLOCATION (cc, sc); \
+ ARRANGER_W_DECLARE_UPDATE_VISIBILITY (cc, sc); \
+ ARRANGER_W_DECLARE_GET_CURSOR (cc, sc); \
+ ARRANGER_W_DECLARE_MOVE_ITEMS_X (cc, sc); \
+ ARRANGER_W_DECLARE_MOVE_ITEMS_Y (cc, sc); \
+ ARRANGER_W_DECLARE_REFRESH_CHILDREN (cc, sc); \
+ ARRANGER_W_DECLARE_SETUP (cc, sc); \
+ ARRANGER_W_DECLARE_SELECT (cc, sc); \
+ ARRANGER_W_DECLARE_SHOW_CONTEXT_MENU (cc, sc); \
+ ARRANGER_W_DECLARE_ON_DRAG_END (cc, sc); \
+ ARRANGER_W_DECLARE_SET_SIZE (cc, sc)
+
+/**
* Creates a timeline widget using the given timeline data.
*/
void
diff --git a/inc/gui/widgets/audio_arranger.h b/inc/gui/widgets/audio_arranger.h
index e5dde51..11d1040 100644
--- a/inc/gui/widgets/audio_arranger.h
+++ b/inc/gui/widgets/audio_arranger.h
@@ -45,44 +45,7 @@ typedef struct _AudioArrangerWidget
} AudioArrangerWidget;
-/**
- * To be called from get_child_position in parent widget.
- *
- * Used to allocate the overlay children.
- */
-void
-audio_arranger_widget_set_allocation (
- AudioArrangerWidget * self,
- GtkWidget * widget,
- GdkRectangle * allocation);
-
-/**
- * Shows context menu.
- *
- * To be called from parent on right click.
- */
-void
-audio_arranger_widget_show_context_menu (AudioArrangerWidget * self);
-
-void
-audio_arranger_widget_refresh_children (
- AudioArrangerWidget * self);
-
-/**
- * Returns the appropriate cursor based on the
- * current hover_x and y.
- */
-ArrangerCursor
-audio_arranger_widget_get_cursor (
- AudioArrangerWidget * self,
- UiOverlayAction action,
- Tool tool);
-
-/**
- * Sets up the widget.
- */
-void
-audio_arranger_widget_setup (
- AudioArrangerWidget * self);
+ARRANGER_W_DECLARE_FUNCS (
+ Audio, audio);
#endif
diff --git a/inc/gui/widgets/automation_arranger.h b/inc/gui/widgets/automation_arranger.h
new file mode 100644
index 0000000..8a6ede6
--- /dev/null
+++ b/inc/gui/widgets/automation_arranger.h
@@ -0,0 +1,101 @@
+/*
+ * Copyright (C) 2018-2019 Alexandros Theodotou <alex at zrythm dot org>
+ *
+ * This file is part of Zrythm
+ *
+ * Zrythm is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Zrythm 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 Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+/**
+ * \file
+ *
+ * Automation arranger API.
+ */
+
+#ifndef __GUI_WIDGETS_AUTOMATION_ARRANGER_H__
+#define __GUI_WIDGETS_AUTOMATION_ARRANGER_H__
+
+#include "audio/position.h"
+#include "gui/backend/tool.h"
+#include "gui/backend/automation_selections.h"
+#include "gui/widgets/arranger.h"
+#include "gui/widgets/main_window.h"
+#include "gui/widgets/piano_roll.h"
+
+#include <gtk/gtk.h>
+
+#define AUTOMATION_ARRANGER_WIDGET_TYPE \
+ (automation_arranger_widget_get_type ())
+G_DECLARE_FINAL_TYPE (
+ AutomationArrangerWidget,
+ automation_arranger_widget,
+ Z, AUTOMATION_ARRANGER_WIDGET,
+ ArrangerWidget)
+
+/**
+ * @addtogroup widgets
+ *
+ * @{
+ */
+
+#define MW_AUTOMATION_ARRANGER MW_CENTER_DOCK->timeline
+
+typedef struct _ArrangerBgWidget ArrangerBgWidget;
+typedef struct AutomationPoint AutomationPoint;
+typedef struct AutomationCurve AutomationCurve;
+typedef struct _AutomationPointWidget
+ AutomationPointWidget;
+typedef struct _AutomationCurveWidget
+ AutomationCurveWidget;
+typedef struct SnapGrid SnapGrid;
+typedef struct AutomationTrack AutomationTrack;
+typedef struct _RegionWidget RegionWidget;
+
+typedef struct _AutomationArrangerWidget
+{
+ ArrangerWidget parent_instance;
+
+ /**
+ * Start AutomationPoint acting on. This is the
+ * AutomationPoint that was clicked, even though
+ * there could be more selected.
+ */
+ AutomationPoint * start_ap;
+ AutomationCurve * start_ac;
+} AutomationArrangerWidget;
+
+ARRANGER_W_DECLARE_FUNCS (
+ Automation, automation);
+ARRANGER_W_DECLARE_CHILD_OBJ_FUNCS (
+ Automation, automation, AutomationPoint, ap);
+ARRANGER_W_DECLARE_CHILD_OBJ_FUNCS (
+ Automation, automation, AutomationCurve, ac);
+
+/**
+ * Create an AutomationPointat the given Position
+ * in the given Track's AutomationTrack.
+ *
+ * @param pos The pre-snapped position.
+ */
+void
+automation_arranger_widget_create_ap (
+ AutomationArrangerWidget * self,
+ const Position * pos,
+ const double start_y);
+
+/**
+ * @}
+ */
+
+#endif
diff --git a/inc/gui/widgets/automation_arranger_bg.h b/inc/gui/widgets/automation_arranger_bg.h
new file mode 100644
index 0000000..0c046a3
--- /dev/null
+++ b/inc/gui/widgets/automation_arranger_bg.h
@@ -0,0 +1,71 @@
+/*
+ * Copyright (C) 2019 Alexandros Theodotou <alex at zrythm dot org>
+ *
+ * This file is part of Zrythm
+ *
+ * Zrythm is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Zrythm 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 Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+/**
+ * \file
+ *
+ * The background (main overlay child) of the
+ * AutomationArrangerWidget.
+ */
+
+#ifndef __GUI_WIDGETS_AUTOMATION_ARRANGER_BG_H__
+#define __GUI_WIDGETS_AUTOMATION_ARRANGER_BG_H__
+
+#include "gui/widgets/arranger_bg.h"
+
+#include <gtk/gtk.h>
+
+#define AUTOMATION_ARRANGER_BG_WIDGET_TYPE \
+ (automation_arranger_bg_widget_get_type ())
+G_DECLARE_FINAL_TYPE (
+ AutomationArrangerBgWidget,
+ automation_arranger_bg_widget,
+ Z, AUTOMATION_ARRANGER_BG_WIDGET,
+ ArrangerBgWidget)
+
+/**
+ * @addtogroup widgets
+ *
+ * @{
+ */
+
+#define AUTOMATION_ARRANGER_BG \
+ Z_AUTOMATION_ARRANGER_BG_WIDGET ( \
+ arranger_widget_get_private ( \
+ Z_ARRANGER_WIDGET (MW_AUTOMATION_ARRANGER))->bg)
+
+typedef struct _AutomationArrangerBgWidget
+{
+ ArrangerBgWidget parent_instance;
+} AutomationArrangerBgWidget;
+
+/**
+ * Creates a AutomationArrangerBgWidget for the given
+ * arranger and ruler.
+ */
+AutomationArrangerBgWidget *
+automation_arranger_bg_widget_new (
+ RulerWidget * ruler,
+ ArrangerWidget * arranger);
+
+/**
+ * @}
+ */
+
+#endif
diff --git a/inc/gui/widgets/automation_region.h b/inc/gui/widgets/automation_region.h
new file mode 100644
index 0000000..fdfcd29
--- /dev/null
+++ b/inc/gui/widgets/automation_region.h
@@ -0,0 +1,65 @@
+/*
+ * Copyright (C) 2019 Alexandros Theodotou <alex at zrythm dot org>
+ *
+ * This file is part of Zrythm
+ *
+ * Zrythm is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Zrythm 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 Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with Zrythm. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+/**
+ * \file
+ *
+ * Widget for MIDI regions, inheriting from
+ * RegionWidget.
+ */
+
+#ifndef __GUI_WIDGETS_AUTOMATION_REGION_H__
+#define __GUI_WIDGETS_AUTOMATION_REGION_H__
+
+#include "audio/region.h"
+#include "gui/widgets/region.h"
+#include "utils/ui.h"
+
+#include <gtk/gtk.h>
+
+#define AUTOMATION_REGION_WIDGET_TYPE \
+ (automation_region_widget_get_type ())
+G_DECLARE_FINAL_TYPE (
+ AutomationRegionWidget,
+ automation_region_widget,
+ Z, AUTOMATION_REGION_WIDGET,
+ RegionWidget);
+
+typedef struct Region AutomationRegion;
+
+/**
+ * A widget that represents a AutomationRegion in the
+ * TimelineArrangerWidget.
+ *
+ * It displays the MidiNotes of the Region in
+ * miniature size.
+ */
+typedef struct _AutomationRegionWidget
+{
+ RegionWidget parent_instance;
+} AutomationRegionWidget;
+
+/**
+ * Creates a region.
+ */
+AutomationRegionWidget *
+automation_region_widget_new (
+ Region * automation_region);
+
+#endif
diff --git a/inc/gui/widgets/chord_arranger.h b/inc/gui/widgets/chord_arranger.h
new file mode 100644
index 0000000..705619b
--- /dev/null
+++ b/inc/gui/widgets/chord_arranger.h
@@ -0,0 +1,75 @@
+/*
+ * Copyright (C) 2018-2019 Alexandros Theodotou <alex at zrythm dot org>
+ *
+ * This file is part of Zrythm
+ *
+ * Zrythm is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Zrythm 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 Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+#ifndef __GUI_WIDGETS_CHORD_ARRANGER_H__
+#define __GUI_WIDGETS_CHORD_ARRANGER_H__
+
+#include "gui/backend/tool.h"
+#include "gui/widgets/arranger.h"
+#include "gui/widgets/main_window.h"
+#include "gui/widgets/piano_roll.h"
+#include "audio/position.h"
+
+#include <gtk/gtk.h>
+
+#define CHORD_ARRANGER_WIDGET_TYPE \
+ (chord_arranger_widget_get_type ())
+G_DECLARE_FINAL_TYPE (
+ ChordArrangerWidget,
+ chord_arranger_widget,
+ Z, CHORD_ARRANGER_WIDGET,
+ ArrangerWidget)
+
+#define CHORD_ARRANGER MW_PIANO_ROLL->arranger
+
+typedef struct _ArrangerBgWidget ArrangerBgWidget;
+typedef struct ChordObject ChordObject;
+typedef struct _ChordObjectWidget ChordObjectWidget;
+typedef struct SnapGrid SnapGrid;
+typedef struct AutomationPoint AutomationPoint;
+typedef struct Region ChordRegion;
+typedef struct Channel Channel;
+
+typedef struct _ChordArrangerWidget
+{
+ ArrangerWidget parent_instance;
+
+ /**
+ * Start ChordObject acting on. This is the
+ * ChordObject that was clicked, even though
+ * there could be more selected.
+ */
+ ChordObject * start_chord_object;
+} ChordArrangerWidget;
+
+ARRANGER_W_DECLARE_FUNCS (
+ Chord, chord);
+ARRANGER_W_DECLARE_CHILD_OBJ_FUNCS (
+ Chord, chord, ChordObject, chord);
+
+/**
+ * Called on drag begin in parent when background is double
+ * clicked (i.e., a note is created).
+ */
+void
+chord_arranger_widget_create_chord (
+ ChordArrangerWidget * self,
+ const Position * pos);
+
+#endif
diff --git a/inc/gui/widgets/chord_arranger_bg.h b/inc/gui/widgets/chord_arranger_bg.h
new file mode 100644
index 0000000..4cc840f
--- /dev/null
+++ b/inc/gui/widgets/chord_arranger_bg.h
@@ -0,0 +1,71 @@
+/*
+ * Copyright (C) 2019 Alexandros Theodotou <alex at zrythm dot org>
+ *
+ * This file is part of Zrythm
+ *
+ * Zrythm is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Zrythm 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 Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+/**
+ * \file
+ *
+ * The background (main overlay child) of the
+ * ChordArrangerWidget.
+ */
+
+#ifndef __GUI_WIDGETS_CHORD_ARRANGER_BG_H__
+#define __GUI_WIDGETS_CHORD_ARRANGER_BG_H__
+
+#include "gui/widgets/arranger_bg.h"
+
+#include <gtk/gtk.h>
+
+#define CHORD_ARRANGER_BG_WIDGET_TYPE \
+ (chord_arranger_bg_widget_get_type ())
+G_DECLARE_FINAL_TYPE (
+ ChordArrangerBgWidget,
+ chord_arranger_bg_widget,
+ Z, CHORD_ARRANGER_BG_WIDGET,
+ ArrangerBgWidget)
+
+/**
+ * @addtogroup widgets
+ *
+ * @{
+ */
+
+#define CHORD_ARRANGER_BG \
+ Z_CHORD_ARRANGER_BG_WIDGET ( \
+ arranger_widget_get_private ( \
+ Z_ARRANGER_WIDGET (MW_CHORD_ARRANGER))->bg)
+
+typedef struct _ChordArrangerBgWidget
+{
+ ArrangerBgWidget parent_instance;
+} ChordArrangerBgWidget;
+
+/**
+ * Creates a ChordArrangerBgWidget for the given
+ * arranger and ruler.
+ */
+ChordArrangerBgWidget *
+chord_arranger_bg_widget_new (
+ RulerWidget * ruler,
+ ArrangerWidget * arranger);
+
+/**
+ * @}
+ */
+
+#endif
diff --git a/inc/gui/widgets/chord_region.h b/inc/gui/widgets/chord_region.h
new file mode 100644
index 0000000..9614187
--- /dev/null
+++ b/inc/gui/widgets/chord_region.h
@@ -0,0 +1,65 @@
+/*
+ * Copyright (C) 2019 Alexandros Theodotou <alex at zrythm dot org>
+ *
+ * This file is part of Zrythm
+ *
+ * Zrythm is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Zrythm 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 Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with Zrythm. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+/**
+ * \file
+ *
+ * Widget for MIDI regions, inheriting from
+ * RegionWidget.
+ */
+
+#ifndef __GUI_WIDGETS_CHORD_REGION_H__
+#define __GUI_WIDGETS_CHORD_REGION_H__
+
+#include "audio/region.h"
+#include "gui/widgets/region.h"
+#include "utils/ui.h"
+
+#include <gtk/gtk.h>
+
+#define CHORD_REGION_WIDGET_TYPE \
+ (chord_region_widget_get_type ())
+G_DECLARE_FINAL_TYPE (
+ ChordRegionWidget,
+ chord_region_widget,
+ Z, CHORD_REGION_WIDGET,
+ RegionWidget);
+
+typedef struct Region ChordRegion;
+
+/**
+ * A widget that represents a ChordRegion in the
+ * TimelineArrangerWidget.
+ *
+ * It displays the MidiNotes of the Region in
+ * miniature size.
+ */
+typedef struct _ChordRegionWidget
+{
+ RegionWidget parent_instance;
+} ChordRegionWidget;
+
+/**
+ * Creates a region.
+ */
+ChordRegionWidget *
+chord_region_widget_new (
+ Region * chord_region);
+
+#endif
diff --git a/inc/gui/widgets/dir.h b/inc/gui/widgets/dir.h
index 7183138..c824d5d 100644
--- a/inc/gui/widgets/dir.h
+++ b/inc/gui/widgets/dir.h
@@ -1,5 +1,24 @@
+/*
+ * Copyright (C) 2019 Alexandros Theodotou <alex at zrythm dot org>
+ *
+ * This file is part of Zrythm
+ *
+ * Zrythm is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Zrythm 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 Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with Zrythm. If not, see <https://www.gnu.org/licenses/>.
+ */
+
/**
- * @dir inc/gui/widgets
+ * @dir inc/gui/widgets
*
* GUI Widgets.
*/
diff --git a/inc/gui/widgets/midi_arranger.h b/inc/gui/widgets/midi_arranger.h
index f11b7b5..96c2349 100644
--- a/inc/gui/widgets/midi_arranger.h
+++ b/inc/gui/widgets/midi_arranger.h
@@ -67,69 +67,14 @@ typedef struct _MidiArrangerWidget
int hovered_note;
} MidiArrangerWidget;
-/**
- * To be called from get_child_position in parent widget.
- *
- * Used to allocate the overlay children.
- */
-void
-midi_arranger_widget_set_allocation (
- MidiArrangerWidget * self,
- GtkWidget * widget,
- GdkRectangle * allocation);
-
-/**
- * Returns the appropriate cursor based on the
- * current hover_x and y.
- */
-ArrangerCursor
-midi_arranger_widget_get_cursor (
- MidiArrangerWidget * self,
- UiOverlayAction action,
- Tool tool);
+ARRANGER_W_DECLARE_FUNCS (
+ Midi, midi);
+ARRANGER_W_DECLARE_CHILD_OBJ_FUNCS (
+ Midi, midi, MidiNote, note);
int
midi_arranger_widget_get_note_at_y (double y);
-MidiNoteWidget *
-midi_arranger_widget_get_hit_midi_note (MidiArrangerWidget * self,
- double x,
- double y);
-
-/**
- * Sets transient notes and actual notes
- * visibility based on the current action.
- */
-void
-midi_arranger_widget_update_visibility (
- MidiArrangerWidget * self);
-
-void
-midi_arranger_widget_select_all (
- MidiArrangerWidget * self,
- int select);
-
-/**
- * Shows context menu.
- *
- * To be called from parent on right click.
- */
-void
-midi_arranger_widget_show_context_menu (
- MidiArrangerWidget * self,
- gdouble x,
- gdouble y);
-
-/**
- * Called on drag begin in parent when a note is hit and the
- * number of clicks is 1.
- */
-void
-midi_arranger_widget_on_drag_begin_note_hit (
- MidiArrangerWidget * self,
- double start_x,
- MidiNoteWidget * midi_note_widget);
-
/**
* Called on drag begin in parent when background is double
* clicked (i.e., a note is created).
@@ -141,33 +86,6 @@ midi_arranger_widget_create_note (
int note,
MidiRegion * region);
-void
-midi_arranger_widget_refresh_size (
- MidiArrangerWidget * self);
-
-/**
- * Sets up the widget.
- */
-void
-midi_arranger_widget_setup (
- MidiArrangerWidget * self);
-
-/**
- * Called when in selection mode.
- *
- * Called by arranger widget during drag_update to find and
- * select the midi notes enclosed in the selection area.
- *
- * @param[in] delete If this is a select-delete
- * operation
- */
-void
-midi_arranger_widget_select (
- MidiArrangerWidget * self,
- double offset_x,
- double offset_y,
- int delete);
-
/**
* Called during drag_update in the parent when
* resizing the selection. It sets the start
@@ -207,28 +125,6 @@ midi_arranger_widget_snap_midi_notes_r (
int dry_run);
/**
- * Moves the MidiArrangerSelections by the given
- * amount of ticks
- *
- * @param ticks_diff Ticks to move by.
- * @param copy_moving 1 if copy-moving.
- */
-void
-midi_arranger_widget_move_items_x (
- MidiArrangerWidget * self,
- long ticks_diff,
- int copy_moving);
-
-/**
- * Called when moving midi notes in drag update in arranger
- * widget for moving up/down (changing note).
- */
-void
-midi_arranger_widget_move_items_y (
- MidiArrangerWidget *self,
- double offset_y);
-
-/**
* if midi_notes are within the min border distance grid
* will auto scroll
*/
@@ -239,21 +135,4 @@ midi_arranger_widget_auto_scroll(
GtkScrolledWindow * scrolled_window,
int transient);
-/**
- * Called on drag end.
- *
- * Sets default cursors back and sets the start midi note
- * to NULL if necessary.
- */
-void
-midi_arranger_widget_on_drag_end (
- MidiArrangerWidget * self);
-
-/**
- * Readd children.
- */
-void
-midi_arranger_widget_refresh_children (
- MidiArrangerWidget * self);
-
#endif
diff --git a/inc/gui/widgets/midi_modifier_arranger.h b/inc/gui/widgets/midi_modifier_arranger.h
index 44fd3e3..4b6d1a3 100644
--- a/inc/gui/widgets/midi_modifier_arranger.h
+++ b/inc/gui/widgets/midi_modifier_arranger.h
@@ -60,94 +60,16 @@ typedef struct _MidiModifierArrangerWidget
int vel_diff;
} MidiModifierArrangerWidget;
-/**
- * To be called from get_child_position in parent widget.
- *
- * Used to allocate the overlay children.
- */
-void
-midi_modifier_arranger_widget_set_allocation (
- MidiModifierArrangerWidget * self,
- GtkWidget * widget,
- GdkRectangle * allocation);
-
-VelocityWidget *
-midi_modifier_arranger_widget_get_hit_velocity (
- MidiModifierArrangerWidget * self,
- double x,
- double y);
-
-/**
- * Returns the appropriate cursor based on the
- * current hover_x and y.
- */
-ArrangerCursor
-midi_modifier_arranger_widget_get_cursor (
- MidiModifierArrangerWidget * self,
- UiOverlayAction action,
- Tool tool);
-
-/**
- * Called when in selection mode.
- *
- * Called by arranger widget during drag_update to find and
- * select the midi notes enclosed in the selection area.
- *
- * @param[in] delete If this is a select-delete
- * operation
- */
-void
-midi_modifier_arranger_widget_select (
- MidiModifierArrangerWidget * self,
- double offset_x,
- double offset_y,
- int delete);
-
-void
-midi_modifier_arranger_widget_update_inspector (
- MidiModifierArrangerWidget * self);
-
-void
-midi_modifier_arranger_widget_select_all (
- MidiModifierArrangerWidget * self,
- int select);
-
-/**
- * Sets transient Velocity and actual Velocity
- * visibility based on the current action.
- */
-void
-midi_modifier_arranger_widget_update_visibility (
- MidiModifierArrangerWidget * self);
-
-/**
- * Shows context menu.
- *
- * To be called from parent on right click.
- */
-void
-midi_modifier_arranger_widget_show_context_menu (
- MidiModifierArrangerWidget * self);
+ARRANGER_W_DECLARE_FUNCS (
+ MidiModifier, midi_modifier);
+ARRANGER_W_DECLARE_CHILD_OBJ_FUNCS (
+ MidiModifier, midi_modifier, Velocity, velocity);
void
midi_modifier_arranger_widget_resize_velocities (
MidiModifierArrangerWidget * self,
double offset_y);
-void
-midi_modifier_arranger_on_drag_begin_vel_hit (
- MidiModifierArrangerWidget * self,
- VelocityWidget * vel_w,
- double start_y);
-
-void
-midi_modifier_arranger_widget_on_drag_end (
- MidiModifierArrangerWidget * self);
-
-void
-midi_modifier_arranger_widget_setup (
- MidiModifierArrangerWidget * self);
-
/**
* Draws a ramp from the start coordinates to the
* given coordinates.
@@ -158,11 +80,4 @@ midi_modifier_arranger_widget_ramp (
double offset_x,
double offset_y);
-/**
- * Readd children.
- */
-void
-midi_modifier_arranger_widget_refresh_children (
- MidiModifierArrangerWidget * self);
-
#endif
diff --git a/inc/gui/widgets/midi_region.h b/inc/gui/widgets/midi_region.h
index f2d0eb4..1446d15 100644
--- a/inc/gui/widgets/midi_region.h
+++ b/inc/gui/widgets/midi_region.h
@@ -35,11 +35,11 @@
#define MIDI_REGION_WIDGET_TYPE \
(midi_region_widget_get_type ())
-G_DECLARE_FINAL_TYPE (MidiRegionWidget,
- midi_region_widget,
- Z,
- MIDI_REGION_WIDGET,
- RegionWidget);
+G_DECLARE_FINAL_TYPE (
+ MidiRegionWidget,
+ midi_region_widget,
+ Z, MIDI_REGION_WIDGET,
+ RegionWidget);
typedef struct Region MidiRegion;
@@ -59,6 +59,7 @@ typedef struct _MidiRegionWidget
* Creates a region.
*/
MidiRegionWidget *
-midi_region_widget_new (MidiRegion * midi_region);
+midi_region_widget_new (
+ Region * midi_region);
#endif
diff --git a/inc/gui/widgets/timeline_arranger.h b/inc/gui/widgets/timeline_arranger.h
index 2f039e5..e9655d2 100644
--- a/inc/gui/widgets/timeline_arranger.h
+++ b/inc/gui/widgets/timeline_arranger.h
@@ -37,11 +37,11 @@
#define TIMELINE_ARRANGER_WIDGET_TYPE \
(timeline_arranger_widget_get_type ())
-G_DECLARE_FINAL_TYPE (TimelineArrangerWidget,
- timeline_arranger_widget,
- Z,
- TIMELINE_ARRANGER_WIDGET,
- ArrangerWidget)
+G_DECLARE_FINAL_TYPE (
+ TimelineArrangerWidget,
+ timeline_arranger_widget,
+ Z, TIMELINE_ARRANGER_WIDGET,
+ ArrangerWidget)
/**
* @addtogroup widgets
@@ -71,7 +71,9 @@ typedef struct _TimelineArrangerWidget
ArrangerWidget parent_instance;
/**
- * Object first clicked is stored in start_*.
+ * Start Region acting on. This is the
+ * Region that was clicked, even though
+ * there could be more selected.
*/
Region * start_region;
@@ -79,9 +81,6 @@ typedef struct _TimelineArrangerWidget
* drag_begin. */
int start_region_was_selected;
- AutomationPoint * start_ap;
- AutomationCurve * start_ac;
- ChordObject * start_chord;
ScaleObject * start_scale;
Marker * start_marker;
@@ -103,16 +102,14 @@ typedef struct _TimelineArrangerWidget
int resizing_range_start;
} TimelineArrangerWidget;
-/**
- * To be called from get_child_position in parent widget.
- *
- * Used to allocate the overlay children.
- */
-void
-timeline_arranger_widget_set_allocation (
- TimelineArrangerWidget * self,
- GtkWidget * widget,
- GdkRectangle * allocation);
+ARRANGER_W_DECLARE_FUNCS (
+ Timeline, timeline);
+ARRANGER_W_DECLARE_CHILD_OBJ_FUNCS (
+ Timeline, timeline, Region, region);
+ARRANGER_W_DECLARE_CHILD_OBJ_FUNCS (
+ Timeline, timeline, ScaleObject, scale);
+ARRANGER_W_DECLARE_CHILD_OBJ_FUNCS (
+ Timeline, timeline, Marker, marker);
void
timeline_arranger_widget_snap_range_r (
@@ -143,24 +140,6 @@ timeline_arranger_widget_get_automation_track_at_y (
double y);
/**
- * Sets transient object and actual object
- * visibility based on the current action.
- */
-void
-timeline_arranger_widget_update_visibility (
- TimelineArrangerWidget * self);
-
-/**
- * Returns the appropriate cursor based on the
- * current hover_x and y.
- */
-ArrangerCursor
-timeline_arranger_widget_get_cursor (
- TimelineArrangerWidget * self,
- UiOverlayAction action,
- Tool tool);
-
-/**
* Determines the selection time (objects/range)
* and sets it.
*/
@@ -170,86 +149,20 @@ timeline_arranger_widget_set_select_type (
double y);
/**
- * Declares the get hit function.
- */
-#define GET_HIT_WIDGET(cc,sc) \
- cc##Widget * \
- timeline_arranger_widget_get_hit_##sc ( \
- TimelineArrangerWidget * self, \
- double x, \
- double y)
-
-/**
- * Declares the drag begin hit function.
- */
-#define ON_DRAG_BEGIN_X_HIT(cc,sc) \
- void \
- timeline_arranger_widget_on_drag_begin_##sc##_hit ( \
- TimelineArrangerWidget * self, \
- double start_x, \
- cc##Widget * rw)
-
-/**
- * Sets up a timeline object by declaring the following
- * functions:
- * - get hit
- * - on drag begin hit
- */
-#define SETUP_CHILD_OBJECT_FULL(cc,sc) \
-GET_HIT_WIDGET (cc, sc); \
-ON_DRAG_BEGIN_X_HIT (cc, sc)
-
-SETUP_CHILD_OBJECT_FULL (Region, region);
-SETUP_CHILD_OBJECT_FULL (ChordObject, chord);
-SETUP_CHILD_OBJECT_FULL (ScaleObject, scale);
-SETUP_CHILD_OBJECT_FULL (Marker, marker);
-SETUP_CHILD_OBJECT_FULL (AutomationPoint, ap);
-SETUP_CHILD_OBJECT_FULL (AutomationCurve, curve);
-
-#undef GET_HIT_WIDGET
-#undef ON_DRAG_BEGIN_X_HIT
-#undef SETUP_CHILD_OBJECT_FULL
-
-void
-timeline_arranger_widget_select_all (
- TimelineArrangerWidget * self,
- int select);
-
-/**
- * Shows context menu.
- *
- * To be called from parent on right click.
- */
-void
-timeline_arranger_widget_show_context_menu (
- TimelineArrangerWidget * self,
- gdouble x,
- gdouble y);
-
-/**
- * Create an AutomationPointat the given Position
- * in the given Track's AutomationTrack.
- *
- * @param pos The pre-snapped position.
- */
-void
-timeline_arranger_widget_create_ap (
- TimelineArrangerWidget * self,
- AutomationTrack * at,
- const Position * pos,
- const double start_y);
-
-/**
* Create a Region at the given Position in the
* given Track's given TrackLane.
*
* @param pos The pre-snapped position.
+ * @param track Track, if non-automation.
+ * @param lane TrackLane, if midi/audio region.
+ * @param at AutomationTrack, if automation Region.
*/
void
timeline_arranger_widget_create_region (
TimelineArrangerWidget * self,
- Track * track,
- TrackLane * lane,
+ Track * track,
+ TrackLane * lane,
+ AutomationTrack * at,
const Position * pos);
/**
@@ -268,15 +181,15 @@ timeline_arranger_widget_create_chord_or_scale (
const Position * pos);
/**
- * Create a ChordObject at the given Position in the
- * given Track.
+ * Create a chord Region at the given Position in
+ * the given Track.
*
* @param pos The pre-snapped position.
*/
void
timeline_arranger_widget_create_chord (
TimelineArrangerWidget * self,
- Track * track,
+ Track * track,
const Position * pos);
/**
@@ -304,22 +217,6 @@ timeline_arranger_widget_create_marker (
const Position * pos);
/**
- * First determines the selection type (objects/
- * range), then either finds and selects items or
- * selects a range.
- *
- * @param[in] delete If this is a select-delete
- * operation
- */
-void
-timeline_arranger_widget_select (
- TimelineArrangerWidget * self,
- const double offset_x,
- const double offset_y,
- const int delete);
-
-
-/**
* Snaps both the transients (to show in the GUI)
* and the actual regions.
*
@@ -356,59 +253,8 @@ timeline_arranger_widget_snap_regions_r (
int dry_run);
/**
- * Moves the TimelineSelections by the given
- * amount of ticks.
- *
- * @param ticks_diff Ticks to move by.
- * @param copy_moving 1 if copy-moving.
- */
-void
-timeline_arranger_widget_move_items_x (
- TimelineArrangerWidget * self,
- long ticks_diff,
- int copy_moving);
-
-void
-timeline_arranger_widget_move_items_y (
- TimelineArrangerWidget * self,
- double offset_y);
-
-void
-timeline_arranger_widget_on_drag_end (
- TimelineArrangerWidget * self);
-
-
-/**
- * Sets width to ruler width and height to
- * tracklist height.
- */
-void
-timeline_arranger_widget_set_size (
- TimelineArrangerWidget * self);
-
-/**
- * To be called once at init time.
- */
-void
-timeline_arranger_widget_setup (
- TimelineArrangerWidget * self);
-
-/**
- * Readd children.
- */
-void
-timeline_arranger_widget_refresh_children (
- TimelineArrangerWidget * self);
-
-/**
- * Refreshes visibility of children.
- */
-void
-timeline_arranger_widget_refresh_visibility (
- TimelineArrangerWidget * self);
-
-/**
* Scroll to the given position.
+ * FIXME move to parent?
*/
void
timeline_arranger_widget_scroll_to (
diff --git a/inc/gui/widgets/timeline_bg.h b/inc/gui/widgets/timeline_bg.h
index 0816801..a766b6a 100644
--- a/inc/gui/widgets/timeline_bg.h
+++ b/inc/gui/widgets/timeline_bg.h
@@ -21,7 +21,7 @@
* \file
*
* The background (main overlay child) of the
- * timeline.
+ * TimelineArrangerWidget.
*/
#ifndef __GUI_WIDGETS_TIMELINE_BG_H__
@@ -54,7 +54,8 @@ typedef struct _TimelineBgWidget
} TimelineBgWidget;
/**
- * Creates a timeline widget using the given timeline data.
+ * Creates a TimelineBgWidget for the given
+ * arranger and ruler.
*/
TimelineBgWidget *
timeline_bg_widget_new (RulerWidget * ruler,
diff --git a/inc/plugins/dir.h b/inc/plugins/dir.h
index dee9b82..39a0e3c 100644
--- a/inc/plugins/dir.h
+++ b/inc/plugins/dir.h
@@ -1,3 +1,22 @@
+/*
+ * Copyright (C) 2019 Alexandros Theodotou <alex at zrythm dot org>
+ *
+ * This file is part of Zrythm
+ *
+ * Zrythm is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Zrythm 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 Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with Zrythm. If not, see <https://www.gnu.org/licenses/>.
+ */
+
/**
* @dir inc/plugins
*
diff --git a/inc/project.h b/inc/project.h
index 2928845..026a738 100644
--- a/inc/project.h
+++ b/inc/project.h
@@ -39,6 +39,8 @@
#include "audio/track.h"
#include "audio/tracklist.h"
#include "gui/backend/clip_editor.h"
+#include "gui/backend/automation_selections.h"
+#include "gui/backend/chord_selections.h"
#include "gui/backend/midi_arranger_selections.h"
#include "gui/backend/mixer_selections.h"
#include "gui/backend/timeline_selections.h"
@@ -127,12 +129,24 @@ typedef struct Project
Quantize quantize_midi;
/**
- * Selected objects in the timeline arranger.
+ * Selected objects in the
+ * AutomationArrangerWidget.
+ */
+ AutomationSelections automation_selections;
+
+ /**
+ * Selected objects in the
+ * ChordObjectArrangerWidget.
+ */
+ ChordSelections chord_selections;
+
+ /**
+ * Selected objects in the TimelineArrangerWidget.
*/
TimelineSelections timeline_selections;
/**
- * Selected MidiNote's.
+ * Selected MidiNote's in the MidiArrangerWidget.
*/
MidiArrangerSelections midi_arranger_selections;
diff --git a/inc/utils/algorithms.h b/inc/utils/algorithms.h
new file mode 100644
index 0000000..adbcf5d
--- /dev/null
+++ b/inc/utils/algorithms.h
@@ -0,0 +1,129 @@
+/*
+ * Copyright (C) 2019 Alexandros Theodotou <alex at zrythm dot org>
+ *
+ * This file is part of Zrythm
+ *
+ * Zrythm is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Zrythm 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 Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with Zrythm. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+/**
+ * \file
+ *
+ * Various algorithms.
+ */
+
+#ifndef __UTILS_ALGORITHMS_H__
+#define __UTILS_ALGORITHMS_H__
+
+/**
+ * Conducts binary search on the object's member
+ * array to find the previous or next member closest
+ * to the given one.
+ *
+ * @note This requires that the search value and
+ * the elements in the array are of the same value.
+ *
+ * @param arr The array.
+ * @param sval Value to search with.
+ * @param rprev 1 to return previous element, 0 for
+ * next.
+ * @param count Element count.
+ * @param type Data type of each element. If the
+ * data type is MyStruct then "MyStruct *" should
+ * be passed with the "&" character passed to amp.
+ * @param cmp Comparator function for two elements.
+ * @param amp The & symbol, if the array does not
+ * contain primitives or pointers. In this case,
+ * type must also contain an asterisk.
+ * @param ret Variable to store the return value in.
+ * @param null Value to set to ret if nothing found.
+ */
+#define algorithms_binary_search_nearby( \
+ arr,sval,rprev,count,type,cmp,amp,ret,null) \
+{ \
+ /* init values */ \
+ int first = 0; \
+ int last = count; \
+ int middle = (first + last) / 2; \
+ int pivot_is_before, pivot_succ_is_before; \
+ type pivot; \
+ type pivot_succ; \
+ \
+ /* return if SnapGrid has no entries */ \
+ if (first == last) \
+ { \
+ ret = null; \
+ goto end_binary_search; \
+ } \
+ \
+ /* search loops, exit if pos is not in array */ \
+ while (first <= last) \
+ { \
+ pivot = amp arr[middle]; \
+ pivot_succ = null; \
+ pivot_succ_is_before = 0; \
+ \
+ if (middle == 0 && rprev) { \
+ ret = amp arr[0]; \
+ goto end_binary_search; \
+ } \
+ \
+ /* Return next/previous item if pivot is the
+ * searched position */ \
+ if (cmp (pivot, sval) == 0) { \
+ if (rprev) \
+ ret = amp arr[middle - 1]; \
+ else \
+ ret = amp arr[middle + 1]; \
+ goto end_binary_search; \
+ } \
+ \
+ /* Select pivot successor if possible */ \
+ if (middle < last) \
+ { \
+ pivot_succ = amp arr[middle + 1]; \
+ pivot_succ_is_before = \
+ cmp (pivot_succ, sval) <= 0; \
+ } \
+ pivot_is_before = \
+ cmp (pivot, sval) <= 0; \
+ \
+ /* if pivot and pivot_succ are before pos, search in the second half on next iteration */ \
+ if (pivot_is_before && pivot_succ_is_before) \
+ { \
+ first = middle + 1; \
+ } \
+ /* sval is between pivot and pivot_succ */ \
+ else if (pivot_is_before) \
+ { \
+ if (return_prev) { \
+ ret = pivot; \
+ goto end_binary_search; \
+ } else { \
+ ret = pivot_succ; \
+ goto end_binary_search; \
+ } \
+ } \
+ else { /* if pivot_succ and pivot are behind pos, search in the first half on next iteration */ \
+ last = middle; \
+ } \
+ \
+ /* recalculate middle position */ \
+ middle = (first + last) / 2; \
+ } \
+ ret = null; \
+end_binary_search: ; \
+}
+
+#endif
diff --git a/inc/utils/arrays.h b/inc/utils/arrays.h
index ddc4393..ba1dbdb 100644
--- a/inc/utils/arrays.h
+++ b/inc/utils/arrays.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2018-2019 Alexandros Theodotou <alex@zrythm.org>
+ * Copyright (C) 2018-2019 Alexandros Theodotou <alex at zrythm dot org>
*
* This file is part of Zrythm
*
@@ -57,11 +57,9 @@
arr1,arr2,size,pos,el1,el2) \
for (int ii = size; ii > pos; ii--) \
{ \
- g_message ("setting %d = %d", ii, ii - 1); \
arr1[ii] = arr1[ii - 1]; \
arr2[ii] = arr2[ii - 1]; \
} \
- g_message ("setting %d = the element", pos); \
arr1[pos] = el1; \
arr2[pos] = el2; \
size++;
@@ -79,7 +77,7 @@
array,count,size,type) \
if ((count) == (size)) \
{ \
- (size) *= 2; \
+ (size) = (size) == 0 ? 1 : (size) * 2; \
(array) = \
realloc ((array), sizeof (type) * (size)); \
}
diff --git a/inc/utils/dir.h b/inc/utils/dir.h
index bda22c8..466dc87 100644
--- a/inc/utils/dir.h
+++ b/inc/utils/dir.h
@@ -1,3 +1,22 @@
+/*
+ * Copyright (C) 2019 Alexandros Theodotou <alex at zrythm dot org>
+ *
+ * This file is part of Zrythm
+ *
+ * Zrythm is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Zrythm 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 Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with Zrythm. If not, see <https://www.gnu.org/licenses/>.
+ */
+
/**
* @dir inc/utils
*
diff --git a/inc/utils/stoat.h b/inc/utils/stoat.h
new file mode 100644
index 0000000..731dfc1
--- /dev/null
+++ b/inc/utils/stoat.h
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2019 Alexandros Theodotou <alex at zrythm dot org>
+ *
+ * This file is part of Zrythm
+ *
+ * Zrythm is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Zrythm 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 Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with Zrythm. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+#ifndef __UTILS_STOAT_H__
+#define __UTILS_STOAT_H__
+
+#if defined(__clang__)
+#define REALTIME __attribute__((annotate("realtime")))
+#define NONREALTIME __attribute__((annotate("nonrealtime")))
+#else
+#define REALTIME
+#define NONREALTIME
+#endif
+
+#endif
diff --git a/inc/utils/ui.h b/inc/utils/ui.h
index b54dc4c..73fc4cb 100644
--- a/inc/utils/ui.h
+++ b/inc/utils/ui.h
@@ -371,8 +371,9 @@ ui_pos_to_px_timeline (
* padding.
*/
int
-ui_pos_to_px_piano_roll (Position * pos,
- int use_padding);
+ui_pos_to_px_piano_roll (
+ Position * pos,
+ int use_padding);
/**
* Converts position to px, optionally adding the ruler
@@ -383,6 +384,16 @@ ui_pos_to_px_audio_clip_editor (
Position * pos,
int use_padding);
+int
+ui_pos_to_px_chord_editor (
+ Position * pos,
+ int use_padding);
+
+int
+ui_pos_to_px_automation_editor (
+ Position * pos,
+ int use_padding);
+
/**
* Converts from pixels to position.
*/
diff --git a/meson.build b/meson.build
index c606287..cdf47e7 100644
--- a/meson.build
+++ b/meson.build
@@ -1,3 +1,20 @@
+# Copyright (C) 2019 Alexandros Theodotou <alex at zrythm dot org>
+#
+# This file is part of Zrythm
+#
+# Zrythm is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Affero General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# Zrythm 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 Affero General Public License for more details.
+#
+# You should have received a copy of the GNU Affero General Public License
+# along with Zrythm. If not, see <https://www.gnu.org/licenses/>.
+
project (
'zrythm', ['c', 'cpp'],
version: '0.5.162',
diff --git a/meson_options.txt b/meson_options.txt
index a7f0aed..e8491b8 100644
--- a/meson_options.txt
+++ b/meson_options.txt
@@ -1,3 +1,20 @@
+# Copyright (C) 2019 Alexandros Theodotou <alex at zrythm dot org>
+#
+# This file is part of Zrythm
+#
+# Zrythm is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Affero General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# Zrythm 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 Affero General Public License for more details.
+#
+# You should have received a copy of the GNU Affero General Public License
+# along with Zrythm. If not, see <https://www.gnu.org/licenses/>.
+
option (
'enable_profiling',
type: 'boolean',
diff --git a/po/meson.build b/po/meson.build
index d9b56f7..37508ee 100644
--- a/po/meson.build
+++ b/po/meson.build
@@ -1,3 +1,20 @@
+# Copyright (C) 2019 Alexandros Theodotou <alex at zrythm dot org>
+#
+# This file is part of Zrythm
+#
+# Zrythm is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Affero General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# Zrythm 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 Affero General Public License for more details.
+#
+# You should have received a copy of the GNU Affero General Public License
+# along with Zrythm. If not, see <https://www.gnu.org/licenses/>.
+
i18n = import('i18n')
# define GETTEXT_PACKAGE
diff --git a/resources/icons/ext/Bitcoin_logo.svg b/resources/icons/ext/Bitcoin_logo.svg
deleted file mode 100644
index f58643a..0000000
--- a/resources/icons/ext/Bitcoin_logo.svg
+++ /dev/null
@@ -1,14 +0,0 @@
-<!-- Created with Inkscape (http://www.inkscape.org/) -->
-<svg xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns="http://www.w3.org/2000/svg" height="64.001" width="306.5" version="1.1" xmlns:cc="http://creativecommons.org/ns#" xmlns:dc="http://purl.org/dc/elements/1.1/">
-<g transform="translate(-289.60744,-317.50471)">
-<path d="m352.64,357.25c-4.274,17.143-21.637,27.576-38.782,23.301-17.138-4.274-27.571-21.638-23.295-38.78,4.272-17.145,21.635-27.579,38.775-23.305,17.144,4.274,27.576,21.64,23.302,38.784z" fill="#f7931a"/>
-<path d="m335.71,344.95c0.637-4.258-2.605-6.547-7.038-8.074l1.438-5.768-3.511-0.875-1.4,5.616c-0.923-0.23-1.871-0.447-2.813-0.662l1.41-5.653-3.509-0.875-1.439,5.766c-0.764-0.174-1.514-0.346-2.242-0.527l0.004-0.018-4.842-1.209-0.934,3.75s2.605,0.597,2.55,0.634c1.422,0.355,1.679,1.296,1.636,2.042l-1.638,6.571c0.098,0.025,0.225,0.061,0.365,0.117-0.117-0.029-0.242-0.061-0.371-0.092l-2.296,9.205c-0.174,0.432-0.615,1.08-1.609,0.834,0.035,0.051-2.552-0.637-2.552-0.637l-1.743,4.019,4.569,1.139c0.85,0.213,1.683,0.436,2.503,0.646l-1.453,5.834,3.507,0.875,1.439-5.772c0.958,0.26,1.888,0.5,2.798,0.726l-1.434,5.745,3.511,0.875,1.453-5.823c5.987,1.133,10.489,0.676,12.384-4.739,1.527-4.36-0.076-6.875-3.226-8.515,2.294-0.529,4.022-2.038,4.483-5.155zm-8.022,11.249c-1.085,4.36-8.426,2.003-10.806,1.412l1.928-7.729c2.38,0.594,10.012,1.77,8.878,6.317zm1.086-11.312c-0.99,3.966-7.1,1.951-9.082,1.457l1.748-7.01c1.982,0.494,8.365,1.416,7.334,5.553z" fill="#FFF"/>
-<path fill="#4d4d4d" d="m383.38,336.87c2.595,0,4.837,0.465,6.721,1.378,1.893,0.922,3.455,2.164,4.708,3.726,1.236,1.57,2.156,3.405,2.75,5.508,0.59,2.109,0.886,4.376,0.886,6.803,0,3.728-0.683,7.25-2.062,10.57-1.379,3.325-3.25,6.209-5.63,8.669-2.378,2.457-5.186,4.394-8.424,5.825-3.233,1.432-6.748,2.148-10.522,2.148-0.488,0-1.346-0.014-2.558-0.039s-2.605-0.15-4.165-0.361c-1.57-0.219-3.23-0.543-4.983-0.977-1.752-0.426-3.416-1.023-4.983-1.781l14.012-58.876,12.55-1.945-5.017,20.893c1.074-0.484,2.156-0.859,3.236-1.132,1.081-0.269,2.241-0.409,3.481-0.409zm-10.527,34.671c1.89,0,3.671-0.465,5.344-1.378,1.678-0.914,3.126-2.148,4.339-3.685,1.213-1.544,2.173-3.283,2.873-5.226s1.054-3.97,1.054-6.079c0-2.591-0.433-4.612-1.296-6.073-0.863-1.455-2.46-2.187-4.779-2.187-0.76,0-1.739,0.145-2.953,0.404-1.218,0.275-2.308,0.846-3.285,1.705l-5.342,22.188c0.322,0.057,0.607,0.111,0.85,0.162,0.238,0.055,0.501,0.094,0.763,0.121,0.277,0.031,0.594,0.047,0.977,0.047s0.862,0.001,1.455,0.001z"/>
-<path fill="#4d4d4d" d="m411.46,380.37h-11.987l10.123-42.597h12.069l-10.205,42.597zm5.833-47.787c-1.673,0-3.19-0.498-4.536-1.496-1.357-0.992-2.029-2.519-2.029-4.577,0-1.132,0.23-2.194,0.686-3.196,0.463-1,1.068-1.861,1.826-2.593,0.757-0.726,1.634-1.306,2.63-1.743,1.002-0.43,2.068-0.645,3.204-0.645,1.672,0,3.181,0.498,4.532,1.496,1.346,1.003,2.023,2.53,2.023,4.577,0,1.136-0.229,2.202-0.689,3.202-0.457,1-1.062,1.861-1.82,2.593-0.751,0.727-1.636,1.305-2.63,1.738-1.003,0.437-2.065,0.644-3.197,0.644z"/>
-<path fill="#4d4d4d" d="m432.17,327.16,12.555-1.945-3.083,12.556h13.446l-2.428,9.878h-13.365l-3.56,14.9c-0.328,1.242-0.514,2.402-0.566,3.48-0.059,1.083,0.078,2.013,0.402,2.796,0.322,0.785,0.901,1.39,1.741,1.818,0.836,0.435,2.033,0.654,3.603,0.654,1.293,0,2.553-0.123,3.771-0.367,1.211-0.24,2.438-0.574,3.68-1.011l0.894,9.236c-1.62,0.594-3.374,1.105-5.264,1.535-1.893,0.436-4.134,0.646-6.724,0.646-3.724,0-6.611-0.553-8.668-1.654-2.054-1.109-3.506-2.624-4.375-4.542-0.857-1.911-1.24-4.114-1.133-6.596,0.111-2.488,0.486-5.103,1.133-7.857l7.941-33.527z"/>
-<path fill="#4d4d4d" d="m454.56,363.36c0-3.669,0.594-7.129,1.781-10.368,1.185-3.242,2.892-6.077,5.107-8.51,2.207-2.421,4.896-4.339,8.061-5.747,3.15-1.4,6.677-2.106,10.564-2.106,2.433,0,4.606,0.23,6.518,0.691,1.92,0.465,3.657,1.066,5.228,1.82l-4.134,9.4c-1.08-0.438-2.201-0.824-3.36-1.174-1.16-0.357-2.576-0.529-4.251-0.529-4.001,0-7.164,1.379-9.518,4.128-2.345,2.751-3.526,6.454-3.526,11.099,0,2.753,0.594,4.979,1.786,6.682,1.186,1.703,3.377,2.55,6.558,2.55,1.57,0,3.085-0.164,4.536-0.484,1.462-0.324,2.753-0.732,3.89-1.214l0.895,9.636c-1.516,0.588-3.188,1.119-5.022,1.584-1.838,0.449-4.026,0.682-6.563,0.682-3.349,0-6.184-0.49-8.503-1.455-2.32-0.98-4.237-2.281-5.747-3.929-1.518-1.652-2.608-3.581-3.282-5.795-0.674-2.212-1.018-4.536-1.018-6.961z"/>
-<path fill="#4d4d4d" d="m507.81,381.5c-2.861,0-5.346-0.436-7.454-1.299-2.102-0.863-3.843-2.074-5.22-3.644-1.379-1.562-2.411-3.413-3.118-5.546-0.707-2.132-1.047-4.493-1.047-7.08,0-3.245,0.521-6.489,1.574-9.724,1.048-3.242,2.603-6.155,4.661-8.744,2.042-2.593,4.561-4.713,7.527-6.366,2.963-1.642,6.371-2.468,10.199-2.468,2.809,0,5.281,0.437,7.418,1.3,2.127,0.861,3.879,2.082,5.264,3.644,1.37,1.57,2.411,3.413,3.111,5.549,0.705,2.128,1.053,4.495,1.053,7.084,0,3.235-0.514,6.479-1.534,9.724-1.021,3.229-2.536,6.149-4.536,8.744-1.996,2.589-4.492,4.708-7.49,6.354-2.994,1.646-6.466,2.472-10.408,2.472zm5.991-34.662c-1.777,0-3.348,0.516-4.693,1.535-1.35,1.031-2.484,2.327-3.398,3.89-0.924,1.57-1.609,3.282-2.072,5.143-0.459,1.865-0.684,3.628-0.684,5.303,0,2.703,0.436,4.808,1.293,6.323,0.869,1.507,2.43,2.265,4.699,2.265,1.783,0,3.346-0.512,4.699-1.542,1.342-1.023,2.477-2.32,3.398-3.886,0.918-1.562,1.609-3.279,2.072-5.143,0.453-1.859,0.684-3.632,0.684-5.304,0-2.696-0.434-4.806-1.299-6.319-0.864-1.507-2.432-2.265-4.699-2.265z"/>
-<path fill="#4d4d4d" d="m544.84,380.37h-11.997l10.123-42.597h12.075l-10.201,42.597zm5.824-47.787c-1.672,0-3.188-0.498-4.532-1.496-1.35-0.992-2.028-2.519-2.028-4.577,0-1.132,0.233-2.194,0.69-3.196,0.457-1,1.066-1.861,1.824-2.593,0.753-0.726,1.638-1.306,2.632-1.743,0.996-0.43,2.062-0.645,3.194-0.645,1.676,0,3.19,0.498,4.538,1.496,1.349,1.003,2.03,2.53,2.03,4.577,0,1.136-0.242,2.202-0.695,3.202s-1.062,1.861-1.817,2.593c-0.76,0.727-1.634,1.305-2.63,1.738-1.004,0.437-2.068,0.644-3.206,0.644z"/>
-<path fill="#4d4d4d" d="m563.68,339.71c0.91-0.266,1.926-0.586,3.031-0.934,1.109-0.348,2.348-0.672,3.732-0.964,1.369-0.301,2.914-0.545,4.613-0.734,1.699-0.193,3.635-0.287,5.786-0.287,6.322,0,10.68,1.841,13.086,5.512,2.404,3.671,2.82,8.695,1.26,15.063l-5.514,23h-12.066l5.344-22.516c0.326-1.406,0.582-2.765,0.771-4.093,0.191-1.316,0.18-2.476-0.043-3.48-0.213-0.992-0.715-1.804-1.494-2.433-0.791-0.619-1.986-0.93-3.607-0.93-1.563,0-3.153,0.168-4.776,0.492l-7.857,32.959h-12.071l9.805-40.655z"/>
-</g>
-</svg>
diff --git a/resources/icons/ext/Liberapay_logo_v2_white-on-yellow.svg.LICENSE b/resources/icons/ext/Liberapay_logo_v2_white-on-yellow.svg.LICENSE
new file mode 100644
index 0000000..bd5f715
--- /dev/null
+++ b/resources/icons/ext/Liberapay_logo_v2_white-on-yellow.svg.LICENSE
@@ -0,0 +1,3 @@
+This icon is licensed under the CC0 1.0 license.
+
+For more information see https://liberapay.com/about/logos
diff --git a/resources/icons/ext/pp-logo-200px.png b/resources/icons/ext/pp-logo-200px.png
deleted file mode 100644
index 780c84f..0000000
--- a/resources/icons/ext/pp-logo-200px.png
+++ /dev/null
Binary files differ
diff --git a/resources/meson.build b/resources/meson.build
index a06eb70..40f5f49 100644
--- a/resources/meson.build
+++ b/resources/meson.build
@@ -1,3 +1,20 @@
+# Copyright (C) 2019 Alexandros Theodotou <alex at zrythm dot org>
+#
+# This file is part of Zrythm
+#
+# Zrythm is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Affero General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# Zrythm 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 Affero General Public License for more details.
+#
+# You should have received a copy of the GNU Affero General Public License
+# along with Zrythm. If not, see <https://www.gnu.org/licenses/>.
+
install_subdir (
join_paths ('fonts', 'Segment7Standard'),
install_dir: join_paths (datadir, 'zrythm'))
diff --git a/resources/ui/audio_clip_editor.ui b/resources/ui/audio_clip_editor.ui
index e0910e3..5815397 100644
--- a/resources/ui/audio_clip_editor.ui
+++ b/resources/ui/audio_clip_editor.ui
@@ -2,7 +2,7 @@
<!-- Generated with glade 3.22.1 -->
<!--
- Copyright (C) 2019 Alexandros Theodotou
+ Copyright (C) 2019 Alexandros Theodotou <alex at zrythm dot org>
This file is part of Zrythm
diff --git a/resources/ui/automatable_selector.ui b/resources/ui/automatable_selector.ui
index bc77021..9cab4d2 100644
--- a/resources/ui/automatable_selector.ui
+++ b/resources/ui/automatable_selector.ui
@@ -1,5 +1,25 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- Generated with glade 3.22.1 -->
+<!--
+
+ Copyright (C) 2019 Alexandros Theodotou <alex at zrythm dot org>
+
+ This file is part of Zrythm
+
+ Zrythm is free software: you can redistribute it and/or modify
+ it under the terms of the GNU Affero General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ Zrythm 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 Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License
+ along with Zrythm. If not, see <https://www.gnu.org/licenses/>.
+
+-->
<interface>
<requires lib="gtk+" version="3.20"/>
<template class="AutomatableSelectorPopoverWidget" parent="GtkPopover">
diff --git a/resources/ui/chord_pad.ui b/resources/ui/chord_pad.ui
index eafeceb..7ce304e 100644
--- a/resources/ui/chord_pad.ui
+++ b/resources/ui/chord_pad.ui
@@ -1,5 +1,25 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- Generated with glade 3.22.1 -->
+<!--
+
+ Copyright (C) 2019 Alexandros Theodotou <alex at zrythm dot org>
+
+ This file is part of Zrythm
+
+ Zrythm is free software: you can redistribute it and/or modify
+ it under the terms of the GNU Affero General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ Zrythm 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 Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License
+ along with Zrythm. If not, see <https://www.gnu.org/licenses/>.
+
+-->
<interface>
<requires lib="gtk+" version="3.20"/>
<template class="ChordPadWidget" parent="GtkGrid">
diff --git a/resources/ui/control_room.ui b/resources/ui/control_room.ui
index bcd4b31..5ebed51 100644
--- a/resources/ui/control_room.ui
+++ b/resources/ui/control_room.ui
@@ -1,5 +1,25 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- Generated with glade 3.22.1 -->
+<!--
+
+ Copyright (C) 2019 Alexandros Theodotou <alex at zrythm dot org>
+
+ This file is part of Zrythm
+
+ Zrythm is free software: you can redistribute it and/or modify
+ it under the terms of the GNU Affero General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ Zrythm 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 Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License
+ along with Zrythm. If not, see <https://www.gnu.org/licenses/>.
+
+-->
<interface>
<requires lib="gtk+" version="3.20"/>
<template class="ControlRoomWidget" parent="GtkGrid">
diff --git a/resources/ui/donate_dialog.ui b/resources/ui/donate_dialog.ui
index f7388c2..04a0b34 100644
--- a/resources/ui/donate_dialog.ui
+++ b/resources/ui/donate_dialog.ui
@@ -1,5 +1,25 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- Generated with glade 3.22.1 -->
+<!--
+
+ Copyright (C) 2019 Alexandros Theodotou <alex at zrythm dot org>
+
+ This file is part of Zrythm
+
+ Zrythm is free software: you can redistribute it and/or modify
+ it under the terms of the GNU Affero General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ Zrythm 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 Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License
+ along with Zrythm. If not, see <https://www.gnu.org/licenses/>.
+
+-->
<interface>
<requires lib="gtk+" version="3.20"/>
<template class="DonateDialogWidget" parent="GtkDialog">
diff --git a/resources/ui/expander_box.ui b/resources/ui/expander_box.ui
index 3308863..73971b0 100644
--- a/resources/ui/expander_box.ui
+++ b/resources/ui/expander_box.ui
@@ -1,5 +1,25 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- Generated with glade 3.22.1 -->
+<!--
+
+ Copyright (C) 2019 Alexandros Theodotou <alex at zrythm dot org>
+
+ This file is part of Zrythm
+
+ Zrythm is free software: you can redistribute it and/or modify
+ it under the terms of the GNU Affero General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ Zrythm 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 Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License
+ along with Zrythm. If not, see <https://www.gnu.org/licenses/>.
+
+-->
<interface>
<requires lib="gtk+" version="3.20"/>
<template class="ExpanderBoxWidget" parent="GtkBox">
diff --git a/resources/ui/glade-catalog.xml b/resources/ui/glade-catalog.xml
index 500b471..bbd60aa 100644
--- a/resources/ui/glade-catalog.xml
+++ b/resources/ui/glade-catalog.xml
@@ -1,4 +1,24 @@
<!-- TODO -->
+<!--
+
+ Copyright (C) 2019 Alexandros Theodotou <alex at zrythm dot org>
+
+ This file is part of Zrythm
+
+ Zrythm is free software: you can redistribute it and/or modify
+ it under the terms of the GNU Affero General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ Zrythm 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 Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License
+ along with Zrythm. If not, see <https://www.gnu.org/licenses/>.
+
+-->
<?xml version="1.0" encoding="UTF-8"?>
<glade-catalog name="zrythm" library="zrythm" depends="gtk+">
diff --git a/resources/ui/header_notebook.ui b/resources/ui/header_notebook.ui
index f060ef5..547f68e 100644
--- a/resources/ui/header_notebook.ui
+++ b/resources/ui/header_notebook.ui
@@ -1,5 +1,25 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- Generated with glade 3.22.1 -->
+<!--
+
+ Copyright (C) 2019 Alexandros Theodotou <alex at zrythm dot org>
+
+ This file is part of Zrythm
+
+ Zrythm is free software: you can redistribute it and/or modify
+ it under the terms of the GNU Affero General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ Zrythm 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 Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License
+ along with Zrythm. If not, see <https://www.gnu.org/licenses/>.
+
+-->
<interface>
<requires lib="gtk+" version="3.20"/>
<template class="HeaderNotebookWidget" parent="GtkNotebook">
diff --git a/resources/ui/help_toolbar.ui b/resources/ui/help_toolbar.ui
index 1c8f72f..a9d4980 100644
--- a/resources/ui/help_toolbar.ui
+++ b/resources/ui/help_toolbar.ui
@@ -1,5 +1,25 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- Generated with glade 3.22.1 -->
+<!--
+
+ Copyright (C) 2019 Alexandros Theodotou <alex at zrythm dot org>
+
+ This file is part of Zrythm
+
+ Zrythm is free software: you can redistribute it and/or modify
+ it under the terms of the GNU Affero General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ Zrythm 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 Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License
+ along with Zrythm. If not, see <https://www.gnu.org/licenses/>.
+
+-->
<interface>
<requires lib="gtk+" version="3.20"/>
<template class="HelpToolbarWidget" parent="GtkToolbar">
diff --git a/resources/ui/home_toolbar.ui b/resources/ui/home_toolbar.ui
index c846499..d76be00 100644
--- a/resources/ui/home_toolbar.ui
+++ b/resources/ui/home_toolbar.ui
@@ -1,5 +1,25 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- Generated with glade 3.22.1 -->
+<!--
+
+ Copyright (C) 2019 Alexandros Theodotou <alex at zrythm dot org>
+
+ This file is part of Zrythm
+
+ Zrythm is free software: you can redistribute it and/or modify
+ it under the terms of the GNU Affero General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ Zrythm 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 Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License
+ along with Zrythm. If not, see <https://www.gnu.org/licenses/>.
+
+-->
<interface>
<requires lib="gtk+" version="3.20"/>
<template class="HomeToolbarWidget" parent="GtkToolbar">
diff --git a/resources/ui/marker_dialog.ui b/resources/ui/marker_dialog.ui
index 3e9b105..92c9ad1 100644
--- a/resources/ui/marker_dialog.ui
+++ b/resources/ui/marker_dialog.ui
@@ -1,5 +1,25 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- Generated with glade 3.22.1 -->
+<!--
+
+ Copyright (C) 2019 Alexandros Theodotou <alex at zrythm dot org>
+
+ This file is part of Zrythm
+
+ Zrythm is free software: you can redistribute it and/or modify
+ it under the terms of the GNU Affero General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ Zrythm 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 Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License
+ along with Zrythm. If not, see <https://www.gnu.org/licenses/>.
+
+-->
<interface>
<requires lib="gtk+" version="3.20"/>
<template class="MarkerDialogWidget" parent="GtkDialog">
diff --git a/resources/ui/piano_roll_toolbar.ui b/resources/ui/piano_roll_toolbar.ui
index 48c1a3e..b757020 100644
--- a/resources/ui/piano_roll_toolbar.ui
+++ b/resources/ui/piano_roll_toolbar.ui
@@ -1,5 +1,25 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- Generated with glade 3.22.1 -->
+<!--
+
+ Copyright (C) 2019 Alexandros Theodotou <alex at zrythm dot org>
+
+ This file is part of Zrythm
+
+ Zrythm is free software: you can redistribute it and/or modify
+ it under the terms of the GNU Affero General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ Zrythm 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 Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License
+ along with Zrythm. If not, see <https://www.gnu.org/licenses/>.
+
+-->
<interface>
<requires lib="gtk+" version="3.20"/>
<template class="PianoRollToolbarWidget" parent="GtkToolbar">
diff --git a/resources/ui/port_selector_popover.ui b/resources/ui/port_selector_popover.ui
index d371dc2..b843e8c 100644
--- a/resources/ui/port_selector_popover.ui
+++ b/resources/ui/port_selector_popover.ui
@@ -1,5 +1,25 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- Generated with glade 3.22.1 -->
+<!--
+
+ Copyright (C) 2019 Alexandros Theodotou <alex at zrythm dot org>
+
+ This file is part of Zrythm
+
+ Zrythm is free software: you can redistribute it and/or modify
+ it under the terms of the GNU Affero General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ Zrythm 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 Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License
+ along with Zrythm. If not, see <https://www.gnu.org/licenses/>.
+
+-->
<interface>
<requires lib="gtk+" version="3.20"/>
<template class="PortSelectorPopoverWidget" parent="GtkPopover">
diff --git a/resources/ui/project_toolbar.ui b/resources/ui/project_toolbar.ui
index 4a1523b..b06965e 100644
--- a/resources/ui/project_toolbar.ui
+++ b/resources/ui/project_toolbar.ui
@@ -1,5 +1,25 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- Generated with glade 3.22.1 -->
+<!--
+
+ Copyright (C) 2019 Alexandros Theodotou <alex at zrythm dot org>
+
+ This file is part of Zrythm
+
+ Zrythm is free software: you can redistribute it and/or modify
+ it under the terms of the GNU Affero General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ Zrythm 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 Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License
+ along with Zrythm. If not, see <https://www.gnu.org/licenses/>.
+
+-->
<interface>
<requires lib="gtk+" version="3.20"/>
<template class="ProjectToolbarWidget" parent="GtkToolbar">
diff --git a/resources/ui/route_target_selector.ui b/resources/ui/route_target_selector.ui
index 471efea..050046b 100644
--- a/resources/ui/route_target_selector.ui
+++ b/resources/ui/route_target_selector.ui
@@ -1,5 +1,25 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- Generated with glade 3.22.1 -->
+<!--
+
+ Copyright (C) 2019 Alexandros Theodotou <alex at zrythm dot org>
+
+ This file is part of Zrythm
+
+ Zrythm is free software: you can redistribute it and/or modify
+ it under the terms of the GNU Affero General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ Zrythm 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 Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License
+ along with Zrythm. If not, see <https://www.gnu.org/licenses/>.
+
+-->
<interface>
<requires lib="gtk+" version="3.20"/>
<template class="RouteTargetSelectorPopoverWidget"
diff --git a/resources/ui/shortcuts.ui b/resources/ui/shortcuts.ui
index dd4f017..7915a6a 100644
--- a/resources/ui/shortcuts.ui
+++ b/resources/ui/shortcuts.ui
@@ -1,6 +1,26 @@
<?xml version="1.0" encoding="UTF-8"?>
<interface>
<!-- interface-requires gtk+ 3.17 -->
+<!--
+
+ Copyright (C) 2019 Alexandros Theodotou <alex at zrythm dot org>
+
+ This file is part of Zrythm
+
+ Zrythm is free software: you can redistribute it and/or modify
+ it under the terms of the GNU Affero General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ Zrythm 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 Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License
+ along with Zrythm. If not, see <https://www.gnu.org/licenses/>.
+
+-->
<object class="GtkShortcutsWindow" id="shortcuts-builder">
<property name="modal">1</property>
diff --git a/resources/ui/timeline_toolbar.ui b/resources/ui/timeline_toolbar.ui
index e669ee7..084ea19 100644
--- a/resources/ui/timeline_toolbar.ui
+++ b/resources/ui/timeline_toolbar.ui
@@ -1,5 +1,25 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- Generated with glade 3.22.1 -->
+<!--
+
+ Copyright (C) 2019 Alexandros Theodotou <alex at zrythm dot org>
+
+ This file is part of Zrythm
+
+ Zrythm is free software: you can redistribute it and/or modify
+ it under the terms of the GNU Affero General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ Zrythm 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 Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License
+ along with Zrythm. If not, see <https://www.gnu.org/licenses/>.
+
+-->
<interface>
<requires lib="gtk+" version="3.20"/>
<template class="TimelineToolbarWidget" parent="GtkToolbar">
diff --git a/resources/ui/track_lane.ui b/resources/ui/track_lane.ui
index 06209f4..e299a5f 100644
--- a/resources/ui/track_lane.ui
+++ b/resources/ui/track_lane.ui
@@ -1,5 +1,25 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- Generated with glade 3.22.1 -->
+<!--
+
+ Copyright (C) 2019 Alexandros Theodotou <alex at zrythm dot org>
+
+ This file is part of Zrythm
+
+ Zrythm is free software: you can redistribute it and/or modify
+ it under the terms of the GNU Affero General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ Zrythm 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 Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License
+ along with Zrythm. If not, see <https://www.gnu.org/licenses/>.
+
+-->
<interface>
<requires lib="gtk+" version="3.20"/>
<template class="TrackLaneWidget" parent="GtkGrid">
diff --git a/resources/ui/view_toolbar.ui b/resources/ui/view_toolbar.ui
index 9338c4f..91c1b71 100644
--- a/resources/ui/view_toolbar.ui
+++ b/resources/ui/view_toolbar.ui
@@ -1,5 +1,25 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- Generated with glade 3.22.1 -->
+<!--
+
+ Copyright (C) 2019 Alexandros Theodotou <alex at zrythm dot org>
+
+ This file is part of Zrythm
+
+ Zrythm is free software: you can redistribute it and/or modify
+ it under the terms of the GNU Affero General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ Zrythm 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 Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License
+ along with Zrythm. If not, see <https://www.gnu.org/licenses/>.
+
+-->
<interface>
<requires lib="gtk+" version="3.20"/>
<template class="ViewToolbarWidget" parent="GtkToolbar">
diff --git a/scripts/collect_translatables.sh b/scripts/collect_translatables.sh
index 7174a8a..46bb459 100755
--- a/scripts/collect_translatables.sh
+++ b/scripts/collect_translatables.sh
@@ -1,4 +1,21 @@
#!/usr/bin/env python3
+#
+# Copyright (C) 2019 Alexandros Theodotou <alex at zrythm dot org>
+#
+# This file is part of Zrythm
+#
+# Zrythm is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Affero General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# Zrythm 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 Affero General Public License for more details.
+#
+# You should have received a copy of the GNU Affero General Public License
+# along with Zrythm. If not, see <https://www.gnu.org/licenses/>.
import os
import os.path
diff --git a/scripts/meson_post_install.py b/scripts/meson_post_install.py
index d0248f4..d6ea559 100755
--- a/scripts/meson_post_install.py
+++ b/scripts/meson_post_install.py
@@ -1,4 +1,21 @@
#!/usr/bin/env python3
+#
+# Copyright (C) 2019 Alexandros Theodotou <alex at zrythm dot org>
+#
+# This file is part of Zrythm
+#
+# Zrythm is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Affero General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# Zrythm 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 Affero General Public License for more details.
+#
+# You should have received a copy of the GNU Affero General Public License
+# along with Zrythm. If not, see <https://www.gnu.org/licenses/>.
import os
import subprocess
diff --git a/src/Wrapper.m b/src/Wrapper.m
index 7c056c9..5c32a6f 100644
--- a/src/Wrapper.m
+++ b/src/Wrapper.m
@@ -1,3 +1,22 @@
+/*
+ * Copyright (C) 2019 Alexandros Theodotou <alex at zrythm dot org>
+ *
+ * This file is part of Zrythm
+ *
+ * Zrythm is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Zrythm 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 Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with Zrythm. If not, see <https://www.gnu.org/licenses/>.
+ */
+
#include <Cocoa/Cocoa.h>
void show_on_top(void) {
[NSApp activateIgnoringOtherApps:YES];
diff --git a/src/actions/create_automation_selections_action.c b/src/actions/create_automation_selections_action.c
new file mode 100644
index 0000000..9d54e05
--- /dev/null
+++ b/src/actions/create_automation_selections_action.c
@@ -0,0 +1,141 @@
+/*
+ * Copyright (C) 2019 Alexandros Theodotou <alex at zrythm dot org>
+ *
+ * This file is part of Zrythm
+ *
+ * Zrythm is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Zrythm 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 Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with Zrythm. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+#include "actions/create_automation_selections_action.h"
+#include "audio/chord_object.h"
+#include "audio/chord_track.h"
+#include "audio/marker.h"
+#include "audio/marker_track.h"
+#include "audio/scale_object.h"
+#include "audio/track.h"
+#include "gui/backend/automation_selections.h"
+#include "gui/widgets/center_dock.h"
+#include "gui/widgets/automation_arranger.h"
+#include "project.h"
+#include "utils/flags.h"
+#include "utils/objects.h"
+
+#include <glib/gi18n.h>
+
+/**
+ * The given AutomationSelections must already
+ * contain the created selections in the transient
+ * arrays.
+ *
+ * Note: chord addresses are to be copied.
+ */
+UndoableAction *
+create_automation_selections_action_new (
+ AutomationSelections * ts)
+{
+ CreateAutomationSelectionsAction * self =
+ calloc (1, sizeof (
+ CreateAutomationSelectionsAction));
+ UndoableAction * ua = (UndoableAction *) self;
+ ua->type =
+ UNDOABLE_ACTION_TYPE_CREATE_AUTOMATION_SELECTIONS;
+
+ self->ts = automation_selections_clone (ts);
+
+ return ua;
+}
+
+int
+create_automation_selections_action_do (
+ CreateAutomationSelectionsAction * self)
+{
+ int i;
+
+ AutomationPoint * ap;
+ for (i = 0;
+ i < self->ts->num_automation_points; i++)
+ {
+ /* check if the ap already exists. due to
+ * how the arranger creates regions, the region
+ * should already exist the first time so no
+ * need to do anything. when redoing we will
+ * need to create a clone instead */
+ if (automation_point_find (
+ self->ts->automation_points[i]))
+ continue;
+
+ /* clone the clone */
+ ap =
+ automation_point_clone (
+ self->ts->automation_points[i],
+ AUTOMATION_POINT_CLONE_COPY_MAIN);
+
+ /* add it to track */
+ automation_track_add_ap (
+ ap->at, ap, F_GEN_WIDGET,
+ F_GEN_CURVE_POINTS);
+
+ /* remember new index */
+ automation_point_set_automation_track_and_index (
+ self->ts->automation_points[i],
+ ap->at, ap->index);
+ }
+
+ EVENTS_PUSH (ET_AUTOMATION_SELECTIONS_CREATED,
+ NULL);
+
+ return 0;
+}
+
+int
+create_automation_selections_action_undo (
+ CreateAutomationSelectionsAction * self)
+{
+ int i;
+ AutomationPoint * ap;
+ for (i = 0;
+ i < self->ts->num_automation_points; i++)
+ {
+ /* get the actual region */
+ ap =
+ automation_point_find (
+ self->ts->automation_points[i]);
+ g_warn_if_fail (ap);
+
+ /* remove it */
+ automation_track_remove_ap (
+ ap->at, ap, F_FREE);
+ }
+ EVENTS_PUSH (ET_AUTOMATION_SELECTIONS_REMOVED,
+ NULL);
+
+ return 0;
+}
+
+char *
+create_automation_selections_action_stringize (
+ CreateAutomationSelectionsAction * self)
+{
+ return g_strdup (
+ _("Create Automation Point(s)"));
+}
+
+void
+create_automation_selections_action_free (
+ CreateAutomationSelectionsAction * self)
+{
+ automation_selections_free (self->ts);
+
+ free (self);
+}
diff --git a/src/actions/create_chord_selections_action.c b/src/actions/create_chord_selections_action.c
new file mode 100644
index 0000000..0d5ad38
--- /dev/null
+++ b/src/actions/create_chord_selections_action.c
@@ -0,0 +1,135 @@
+/*
+ * Copyright (C) 2019 Alexandros Theodotou <alex at zrythm dot org>
+ *
+ * This file is part of Zrythm
+ *
+ * Zrythm is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Zrythm 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 Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with Zrythm. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+#include "actions/create_chord_selections_action.h"
+#include "audio/chord_object.h"
+#include "audio/chord_track.h"
+#include "audio/marker.h"
+#include "audio/marker_track.h"
+#include "audio/scale_object.h"
+#include "audio/track.h"
+#include "gui/backend/chord_selections.h"
+#include "gui/widgets/center_dock.h"
+#include "gui/widgets/chord_arranger.h"
+#include "project.h"
+#include "utils/flags.h"
+#include "utils/objects.h"
+
+#include <glib/gi18n.h>
+
+/**
+ * The given ChordSelections must already
+ * contain the created selections in the transient
+ * arrays.
+ *
+ * Note: chord addresses are to be copied.
+ */
+UndoableAction *
+create_chord_selections_action_new (
+ ChordSelections * ts)
+{
+ CreateChordSelectionsAction * self =
+ calloc (1, sizeof (
+ CreateChordSelectionsAction));
+ UndoableAction * ua = (UndoableAction *) self;
+ ua->type =
+ UNDOABLE_ACTION_TYPE_CREATE_CHORD_SELECTIONS;
+
+ self->ts = chord_selections_clone (ts);
+
+ return ua;
+}
+
+int
+create_chord_selections_action_do (
+ CreateChordSelectionsAction * self)
+{
+ int i;
+
+ ChordObject * chord;
+ for (i = 0;
+ i < self->ts->num_chord_objects; i++)
+ {
+ /* check if the region already exists. due to
+ * how the arranger creates regions, the region
+ * should already exist the first time so no
+ * need to do anything. when redoing we will
+ * need to create a clone instead */
+ if (chord_object_find (
+ self->ts->chord_objects[i]))
+ continue;
+
+ /* clone the clone */
+ chord =
+ chord_object_clone (
+ self->ts->chord_objects[i],
+ CHORD_OBJECT_CLONE_COPY_MAIN);
+
+ /* add it to track */
+ chord_track_add_chord (
+ P_CHORD_TRACK,
+ chord);
+ }
+
+ EVENTS_PUSH (ET_CHORD_SELECTIONS_CREATED,
+ NULL);
+
+ return 0;
+}
+
+int
+create_chord_selections_action_undo (
+ CreateChordSelectionsAction * self)
+{
+ int i;
+ ChordObject * chord_object;
+ for (i = 0; i < self->ts->num_chord_objects; i++)
+ {
+ /* get the actual region */
+ chord_object =
+ chord_object_find (
+ self->ts->chord_objects[i]);
+
+ /* remove it */
+ chord_track_remove_chord (
+ P_CHORD_TRACK, chord_object, F_FREE);
+ }
+
+ EVENTS_PUSH (ET_CHORD_SELECTIONS_REMOVED,
+ NULL);
+
+ return 0;
+}
+
+char *
+create_chord_selections_action_stringize (
+ CreateChordSelectionsAction * self)
+{
+ return g_strdup (
+ _("Create Chord(s)"));
+}
+
+void
+create_chord_selections_action_free (
+ CreateChordSelectionsAction * self)
+{
+ chord_selections_free (self->ts);
+
+ free (self);
+}
diff --git a/src/actions/create_midi_arranger_selections_action.c b/src/actions/create_midi_arranger_selections_action.c
index 33908e6..97e8f93 100644
--- a/src/actions/create_midi_arranger_selections_action.c
+++ b/src/actions/create_midi_arranger_selections_action.c
@@ -77,14 +77,11 @@ create_midi_arranger_selections_action_do (
/* find the region */
mn->region =
region_find_by_name (mn->region_name);
- g_message ("region %p", mn->region);
g_return_val_if_fail (mn->region, -1);
/* add it to the region */
midi_region_add_midi_note (
- mn->region,
- mn, F_GEN_WIDGET);
- g_message ("CREATED");
+ mn->region, mn);
}
EVENTS_PUSH (ET_MA_SELECTIONS_CHANGED,
NULL);
diff --git a/src/actions/create_timeline_selections_action.c b/src/actions/create_timeline_selections_action.c
index b1b382c..c12c98b 100644
--- a/src/actions/create_timeline_selections_action.c
+++ b/src/actions/create_timeline_selections_action.c
@@ -91,30 +91,6 @@ create_timeline_selections_action_do (
self->ts->regions[i]->name =
g_strdup (region->name);
}
- ChordObject * chord;
- for (i = 0;
- i < self->ts->num_chord_objects; i++)
- {
- /* check if the region already exists. due to
- * how the arranger creates regions, the region
- * should already exist the first time so no
- * need to do anything. when redoing we will
- * need to create a clone instead */
- if (chord_object_find (
- self->ts->chord_objects[i]))
- continue;
-
- /* clone the clone */
- chord =
- chord_object_clone (
- self->ts->chord_objects[i],
- CHORD_OBJECT_CLONE_COPY_MAIN);
-
- /* add it to track */
- chord_track_add_chord (
- P_CHORD_TRACK,
- chord, F_GEN_WIDGET);
- }
ScaleObject * scale;
for (i = 0;
i < self->ts->num_scale_objects; i++)
@@ -136,8 +112,7 @@ create_timeline_selections_action_do (
/* add it to track */
chord_track_add_scale (
- P_CHORD_TRACK,
- scale, F_GEN_WIDGET);
+ P_CHORD_TRACK, scale);
}
Marker * marker;
for (i = 0;
@@ -160,39 +135,7 @@ create_timeline_selections_action_do (
/* add it to track */
marker_track_add_marker (
- P_MARKER_TRACK,
- marker, F_GEN_WIDGET);
- }
- AutomationPoint * ap;
- for (i = 0;
- i < self->ts->num_automation_points; i++)
- {
- /* check if the ap already exists. due to
- * how the arranger creates regions, the region
- * should already exist the first time so no
- * need to do anything. when redoing we will
- * need to create a clone instead */
- if (automation_point_find (
- self->ts->automation_points[i]))
- continue;
-
- g_message ("NOT FOUND");
-
- /* clone the clone */
- ap =
- automation_point_clone (
- self->ts->automation_points[i],
- AUTOMATION_POINT_CLONE_COPY_MAIN);
-
- /* add it to track */
- automation_track_add_ap (
- ap->at, ap, F_GEN_WIDGET,
- F_GEN_CURVE_POINTS);
-
- /* remember new index */
- automation_point_set_automation_track_and_index (
- self->ts->automation_points[i],
- ap->at, ap->index);
+ P_MARKER_TRACK, marker);
}
EVENTS_PUSH (ET_TL_SELECTIONS_CREATED,
@@ -216,18 +159,6 @@ create_timeline_selections_action_undo (
track_remove_region (
region->lane->track, region, F_FREE);
}
- ChordObject * chord_object;
- for (i = 0; i < self->ts->num_chord_objects; i++)
- {
- /* get the actual region */
- chord_object =
- chord_object_find (
- self->ts->chord_objects[i]);
-
- /* remove it */
- chord_track_remove_chord (
- P_CHORD_TRACK, chord_object, F_FREE);
- }
ScaleObject * scale_object;
for (i = 0; i < self->ts->num_scale_objects; i++)
{
@@ -250,20 +181,6 @@ create_timeline_selections_action_undo (
marker_track_remove_marker (
P_MARKER_TRACK, marker, F_FREE);
}
- AutomationPoint * ap;
- for (i = 0;
- i < self->ts->num_automation_points; i++)
- {
- /* get the actual region */
- ap =
- automation_point_find (
- self->ts->automation_points[i]);
- g_warn_if_fail (ap);
-
- /* remove it */
- automation_track_remove_ap (
- ap->at, ap, F_FREE);
- }
EVENTS_PUSH (ET_TL_SELECTIONS_REMOVED,
NULL);
diff --git a/src/actions/delete_midi_arranger_selections_action.c b/src/actions/delete_midi_arranger_selections_action.c
index 4fca94b..8940bc1 100644
--- a/src/actions/delete_midi_arranger_selections_action.c
+++ b/src/actions/delete_midi_arranger_selections_action.c
@@ -87,8 +87,7 @@ delete_midi_arranger_selections_action_undo (
/* add it to the region */
midi_region_add_midi_note (
- region_find_by_name (mn->region_name),
- mn, F_GEN_WIDGET);
+ region_find_by_name (mn->region_name), mn);
}
EVENTS_PUSH (ET_MA_SELECTIONS_CHANGED,
NULL);
diff --git a/src/actions/duplicate_automation_selections_action.c b/src/actions/duplicate_automation_selections_action.c
new file mode 100644
index 0000000..f0ddfbd
--- /dev/null
+++ b/src/actions/duplicate_automation_selections_action.c
@@ -0,0 +1,160 @@
+/*
+ * Copyright (C) 2019 Alexandros Theodotou <alex at zrythm dot org>
+ *
+ * This file is part of Zrythm
+ *
+ * Zrythm is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Zrythm 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 Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with Zrythm. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+#include "actions/duplicate_automation_selections_action.h"
+#include "audio/track.h"
+#include "gui/backend/automation_selections.h"
+#include "gui/widgets/center_dock.h"
+#include "gui/widgets/chord_object.h"
+#include "gui/widgets/marker.h"
+#include "gui/widgets/region.h"
+#include "gui/widgets/scale_object.h"
+#include "gui/widgets/automation_arranger.h"
+#include "project.h"
+#include "utils/flags.h"
+#include "utils/objects.h"
+
+#include <glib/gi18n.h>
+
+/**
+ * Note: chord addresses are to be copied.
+ */
+UndoableAction *
+duplicate_automation_selections_action_new (
+ AutomationSelections * ts,
+ long ticks,
+ int delta)
+{
+ DuplicateAutomationSelectionsAction * self =
+ calloc (1, sizeof (
+ DuplicateAutomationSelectionsAction));
+ UndoableAction * ua = (UndoableAction *) self;
+ ua->type =
+ UNDOABLE_ACTION_TYPE_DUPLICATE_AUTOMATION_SELECTIONS;
+
+ self->ts = automation_selections_clone (ts);
+ self->ticks = ticks;
+ self->delta = delta;
+
+ return ua;
+}
+
+#define DO_OBJECT( \
+ caps,cc,sc,add_to_track_code,remember_code) \
+ cc * sc; \
+ for (i = 0; i < self->ts->num_##sc##s; i++) \
+ { \
+ /* clone the clone */ \
+ sc = \
+ sc##_clone ( \
+ self->ts->sc##s[i], \
+ caps##_CLONE_COPY_MAIN); \
+ /* add to track */ \
+ add_to_track_code; \
+ /* shift */ \
+ sc##_shift_by_ticks ( \
+ sc, self->ticks, AO_UPDATE_ALL); \
+ /* shift the clone too so we can find it
+ * when undoing */ \
+ sc##_shift_by_ticks ( \
+ self->ts->sc##s[i], self->ticks, \
+ AO_UPDATE_THIS); \
+ /* select it */ \
+ sc##_widget_select ( \
+ sc->widget, F_SELECT); \
+ remember_code; \
+ }
+
+#define UNDO_OBJECT(cc,sc,remove_code) \
+ cc * sc; \
+ for (i = 0; i < self->ts->num_##sc##s; i++) \
+ { \
+ /* find the actual object */ \
+ sc = \
+ sc##_find ( \
+ self->ts->sc##s[i]); \
+ /* unselect it */ \
+ sc##_widget_select ( \
+ sc->widget, F_NO_SELECT); \
+ /* remove it */ \
+ remove_code; \
+ /* unshift the clone */ \
+ sc##_shift_by_ticks ( \
+ self->ts->sc##s[i], - self->ticks, \
+ AO_UPDATE_ALL); \
+ }
+
+int
+duplicate_automation_selections_action_do (
+ DuplicateAutomationSelectionsAction * self)
+{
+ int i;
+
+ /*DO_OBJECT (*/
+ /*AUTOMATION_POINT, AutomationPoint,*/
+ /*automation_point,*/
+ /*[> add <]*/
+ /*automation_track_add_automation_point (*/
+ /*TRACKLIST,*/
+ /*scale_object, F_GEN_WIDGET),);*/
+
+ EVENTS_PUSH (ET_AUTOMATION_SELECTIONS_CHANGED,
+ NULL);
+
+ return 0;
+}
+
+int
+duplicate_automation_selections_action_undo (
+ DuplicateAutomationSelectionsAction * self)
+{
+ int i;
+
+ /* TODO */
+ /*UNDO_OBJECT (*/
+ /*AutomationPoint, automation_point,*/
+ /*[> remove <]*/
+ /*g_message ("removing");*/
+ /*position_print_simple (&marker->pos);*/
+ /*marker_track_remove_marker (*/
+ /*P_MARKER_TRACK,*/
+ /*marker, F_FREE));*/
+
+ EVENTS_PUSH (ET_AUTOMATION_SELECTIONS_CHANGED,
+ NULL);
+
+ return 0;
+}
+
+char *
+duplicate_automation_selections_action_stringize (
+ DuplicateAutomationSelectionsAction * self)
+{
+ return g_strdup (
+ _("Duplicate Automation"));
+}
+
+void
+duplicate_automation_selections_action_free (
+ DuplicateAutomationSelectionsAction * self)
+{
+ automation_selections_free (self->ts);
+
+ free (self);
+}
diff --git a/src/actions/duplicate_chord_selections_action.c b/src/actions/duplicate_chord_selections_action.c
new file mode 100644
index 0000000..66535f4
--- /dev/null
+++ b/src/actions/duplicate_chord_selections_action.c
@@ -0,0 +1,162 @@
+/*
+ * Copyright (C) 2019 Alexandros Theodotou <alex at zrythm dot org>
+ *
+ * This file is part of Zrythm
+ *
+ * Zrythm is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Zrythm 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 Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with Zrythm. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+#include "actions/duplicate_chord_selections_action.h"
+#include "audio/chord_track.h"
+#include "audio/chord_object.h"
+#include "audio/marker.h"
+#include "audio/marker_track.h"
+#include "audio/scale_object.h"
+#include "audio/track.h"
+#include "gui/backend/chord_selections.h"
+#include "gui/widgets/center_dock.h"
+#include "gui/widgets/chord_object.h"
+#include "gui/widgets/marker.h"
+#include "gui/widgets/region.h"
+#include "gui/widgets/scale_object.h"
+#include "gui/widgets/chord_arranger.h"
+#include "project.h"
+#include "utils/flags.h"
+#include "utils/objects.h"
+
+#include <glib/gi18n.h>
+
+/**
+ * Note: chord addresses are to be copied.
+ */
+UndoableAction *
+duplicate_chord_selections_action_new (
+ ChordSelections * ts,
+ long ticks,
+ int delta)
+{
+ DuplicateChordSelectionsAction * self =
+ calloc (1, sizeof (
+ DuplicateChordSelectionsAction));
+ UndoableAction * ua = (UndoableAction *) self;
+ ua->type =
+ UNDOABLE_ACTION_TYPE_DUPLICATE_CHORD_SELECTIONS;
+
+ self->ts = chord_selections_clone (ts);
+ self->ticks = ticks;
+ self->delta = delta;
+
+ return ua;
+}
+
+#define DO_OBJECT( \
+ caps,cc,sc,add_to_track_code,remember_code) \
+ cc * sc; \
+ for (i = 0; i < self->ts->num_##sc##s; i++) \
+ { \
+ /* clone the clone */ \
+ sc = \
+ sc##_clone ( \
+ self->ts->sc##s[i], \
+ caps##_CLONE_COPY_MAIN); \
+ /* add to track */ \
+ add_to_track_code; \
+ /* shift */ \
+ sc##_shift_by_ticks ( \
+ sc, self->ticks, AO_UPDATE_ALL); \
+ /* shift the clone too so we can find it
+ * when undoing */ \
+ sc##_shift_by_ticks ( \
+ self->ts->sc##s[i], self->ticks, \
+ AO_UPDATE_THIS); \
+ /* select it */ \
+ sc##_widget_select ( \
+ sc->widget, F_SELECT); \
+ remember_code; \
+ }
+
+#define UNDO_OBJECT(cc,sc,remove_code) \
+ cc * sc; \
+ for (i = 0; i < self->ts->num_##sc##s; i++) \
+ { \
+ /* find the actual object */ \
+ sc = \
+ sc##_find ( \
+ self->ts->sc##s[i]); \
+ /* unselect it */ \
+ sc##_widget_select ( \
+ sc->widget, F_NO_SELECT); \
+ /* remove it */ \
+ remove_code; \
+ /* unshift the clone */ \
+ sc##_shift_by_ticks ( \
+ self->ts->sc##s[i], - self->ticks, \
+ AO_UPDATE_ALL); \
+ }
+
+int
+duplicate_chord_selections_action_do (
+ DuplicateChordSelectionsAction * self)
+{
+ int i;
+
+ DO_OBJECT (
+ CHORD_OBJECT, ChordObject, chord_object,
+ /* add */
+ chord_track_add_chord (
+ P_CHORD_TRACK,
+ chord_object, F_GEN_WIDGET),);
+
+ EVENTS_PUSH (ET_CHORD_SELECTIONS_CHANGED,
+ NULL);
+
+ return 0;
+}
+
+int
+duplicate_chord_selections_action_undo (
+ DuplicateChordSelectionsAction * self)
+{
+ int i;
+
+ UNDO_OBJECT (
+ ChordObject, chord_object,
+ /* remove */
+ chord_track_remove_chord (
+ P_CHORD_TRACK,
+ chord_object, F_FREE));
+
+ EVENTS_PUSH (ET_CHORD_SELECTIONS_CHANGED,
+ NULL);
+
+ return 0;
+}
+
+char *
+duplicate_chord_selections_action_stringize (
+ DuplicateChordSelectionsAction * self)
+{
+ return g_strdup (
+ _("Duplicate Chord(s)"));
+}
+
+void
+duplicate_chord_selections_action_free (
+ DuplicateChordSelectionsAction * self)
+{
+ chord_selections_free (self->ts);
+
+ free (self);
+}
+
diff --git a/src/actions/duplicate_midi_arranger_selections_action.c b/src/actions/duplicate_midi_arranger_selections_action.c
index c4e2842..b7c96e1 100644
--- a/src/actions/duplicate_midi_arranger_selections_action.c
+++ b/src/actions/duplicate_midi_arranger_selections_action.c
@@ -66,7 +66,7 @@ duplicate_midi_arranger_selections_action_do (
/* add and shift it */
midi_region_add_midi_note (
- mn->region, mn, F_GEN_WIDGET);
+ mn->region, mn);
midi_note_shift_by_ticks (
mn, self->ticks, AO_UPDATE_ALL);
midi_note_shift_pitch (
diff --git a/src/actions/duplicate_timeline_selections_action.c b/src/actions/duplicate_timeline_selections_action.c
index 9d96423..a1c9abf 100644
--- a/src/actions/duplicate_timeline_selections_action.c
+++ b/src/actions/duplicate_timeline_selections_action.c
@@ -123,38 +123,21 @@ duplicate_timeline_selections_action_do (
g_strdup (region->name));
DO_OBJECT (
- CHORD_OBJECT, ChordObject, chord_object,
- /* add */
- chord_track_add_chord (
- P_CHORD_TRACK,
- chord_object, F_GEN_WIDGET),);
-
- DO_OBJECT (
SCALE_OBJECT, ScaleObject, scale_object,
/* add */
chord_track_add_scale (
- P_CHORD_TRACK,
- scale_object, F_GEN_WIDGET),);
+ P_CHORD_TRACK, scale_object),);
DO_OBJECT (
MARKER, Marker, marker,
/* add */
marker_track_add_marker (
- P_MARKER_TRACK,
- marker, F_GEN_WIDGET),
+ P_MARKER_TRACK, marker),
/* remember the new name */
g_free (self->ts->markers[i]->name);
self->ts->markers[i]->name =
g_strdup (marker->name));
- /*DO_OBJECT (*/
- /*AUTOMATION_POINT, AutomationPoint,*/
- /*automation_point,*/
- /*[> add <]*/
- /*automation_track_add_automation_point (*/
- /*TRACKLIST,*/
- /*scale_object, F_GEN_WIDGET),);*/
-
EVENTS_PUSH (ET_TL_SELECTIONS_CHANGED,
NULL);
@@ -174,12 +157,6 @@ duplicate_timeline_selections_action_undo (
region->lane->track,
region, F_FREE));
UNDO_OBJECT (
- ChordObject, chord_object,
- /* remove */
- chord_track_remove_chord (
- P_CHORD_TRACK,
- chord_object, F_FREE));
- UNDO_OBJECT (
ScaleObject, scale_object,
/* remove */
chord_track_remove_scale (
@@ -188,8 +165,6 @@ duplicate_timeline_selections_action_undo (
UNDO_OBJECT (
Marker, marker,
/* remove */
- g_message ("removing");
- position_print_simple (&marker->pos);
marker_track_remove_marker (
P_MARKER_TRACK,
marker, F_FREE));
diff --git a/src/actions/meson.build b/src/actions/meson.build
index 4f1e660..7190721 100644
--- a/src/actions/meson.build
+++ b/src/actions/meson.build
@@ -1,3 +1,20 @@
+# Copyright (C) 2019 Alexandros Theodotou <alex at zrythm dot org>
+#
+# This file is part of Zrythm
+#
+# Zrythm is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Affero General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# Zrythm 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 Affero General Public License for more details.
+#
+# You should have received a copy of the GNU Affero General Public License
+# along with Zrythm. If not, see <https://www.gnu.org/licenses/>.
+
action_srcs = [
'actions.c',
'create_plugins_action.c',
diff --git a/src/actions/move_automation_selections_action.c b/src/actions/move_automation_selections_action.c
new file mode 100644
index 0000000..678e2bf
--- /dev/null
+++ b/src/actions/move_automation_selections_action.c
@@ -0,0 +1,124 @@
+/*
+ * Copyright (C) 2019 Alexandros Theodotou <alex at zrythm dot org>
+ *
+ * This file is part of Zrythm
+ *
+ * Zrythm is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Zrythm 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 Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with Zrythm. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+#include "actions/move_automation_selections_action.h"
+#include "audio/track.h"
+#include "gui/backend/automation_selections.h"
+#include "gui/widgets/center_dock.h"
+#include "gui/widgets/automation_arranger.h"
+#include "project.h"
+
+#include <glib/gi18n.h>
+
+/**
+ * Note: this action will add delta beats
+ * to start and end pos of all selected midi_notes */
+UndoableAction *
+move_automation_selections_action_new (
+ AutomationSelections * ts,
+ long ticks,
+ int delta)
+{
+ MoveAutomationSelectionsAction * self =
+ calloc (1, sizeof (
+ MoveAutomationSelectionsAction));
+ UndoableAction * ua = (UndoableAction *) self;
+ ua->type =
+ UNDOABLE_ACTION_TYPE_MOVE_AUTOMATION_SELECTIONS;
+
+ self->ts = automation_selections_clone (ts);
+ self->delta = delta;
+ self->ticks = ticks;
+ self->first_call = 1;
+
+ return ua;
+}
+
+#define SHIFT_OBJ(cc,sc,ticks) \
+ cc * sc; \
+ for (i = 0; i < self->ts->num_##sc##s; i++) \
+ { \
+ /* get the actual object */ \
+ sc = sc##_find (self->ts->sc##s[i]); \
+ g_warn_if_fail (sc); \
+ /* shift the actual object */ \
+ sc##_shift_by_ticks ( \
+ sc, ticks, AO_UPDATE_ALL); \
+ /* also shift the copy */ \
+ sc##_shift_by_ticks ( \
+ self->ts->sc##s[i], ticks, AO_UPDATE_THIS); \
+ }
+
+int
+move_automation_selections_action_do (
+ MoveAutomationSelectionsAction * self)
+{
+ int i;
+
+#define SHIFT_OBJ_POSITIVE(cc,sc) \
+ SHIFT_OBJ (cc, sc, self->ticks)
+
+ if (!self->first_call)
+ {
+ SHIFT_OBJ_POSITIVE (
+ AutomationPoint, automation_point);
+ }
+
+ EVENTS_PUSH (ET_AUTOMATION_SELECTIONS_CHANGED,
+ NULL);
+
+ self->first_call = 0;
+
+ return 0;
+}
+
+int
+move_automation_selections_action_undo (
+ MoveAutomationSelectionsAction * self)
+{
+ int i;
+
+#define SHIFT_OBJ_NEGATIVE(cc,sc) \
+ SHIFT_OBJ (cc, sc, - self->ticks)
+
+ SHIFT_OBJ_NEGATIVE (
+ AutomationPoint, automation_point);
+
+ EVENTS_PUSH (ET_AUTOMATION_SELECTIONS_CHANGED,
+ NULL);
+
+ return 0;
+}
+
+char *
+move_automation_selections_action_stringize (
+ MoveAutomationSelectionsAction * self)
+{
+ return g_strdup (
+ _("Move Automation"));
+}
+
+void
+move_automation_selections_action_free (
+ MoveAutomationSelectionsAction * self)
+{
+ automation_selections_free (self->ts);
+
+ free (self);
+}
diff --git a/src/actions/move_chord_selections_action.c b/src/actions/move_chord_selections_action.c
new file mode 100644
index 0000000..8fff277
--- /dev/null
+++ b/src/actions/move_chord_selections_action.c
@@ -0,0 +1,124 @@
+/*
+ * Copyright (C) 2019 Alexandros Theodotou <alex at zrythm dot org>
+ *
+ * This file is part of Zrythm
+ *
+ * Zrythm is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Zrythm 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 Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with Zrythm. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+#include "actions/move_chord_selections_action.h"
+#include "audio/track.h"
+#include "gui/backend/chord_selections.h"
+#include "gui/widgets/center_dock.h"
+#include "gui/widgets/chord_arranger.h"
+#include "project.h"
+
+#include <glib/gi18n.h>
+
+/**
+ * Note: this action will add delta beats
+ * to start and end pos of all selected midi_notes */
+UndoableAction *
+move_chord_selections_action_new (
+ ChordSelections * ts,
+ long ticks,
+ int delta)
+{
+ MoveChordSelectionsAction * self =
+ calloc (1, sizeof (
+ MoveChordSelectionsAction));
+ UndoableAction * ua = (UndoableAction *) self;
+ ua->type =
+ UNDOABLE_ACTION_TYPE_MOVE_CHORD_SELECTIONS;
+
+ self->ts = chord_selections_clone (ts);
+ self->delta = delta;
+ self->ticks = ticks;
+ self->first_call = 1;
+
+ return ua;
+}
+
+#define SHIFT_OBJ(cc,sc,ticks) \
+ cc * sc; \
+ for (i = 0; i < self->ts->num_##sc##s; i++) \
+ { \
+ /* get the actual object */ \
+ sc = sc##_find (self->ts->sc##s[i]); \
+ g_warn_if_fail (sc); \
+ /* shift the actual object */ \
+ sc##_shift_by_ticks ( \
+ sc, ticks, AO_UPDATE_ALL); \
+ /* also shift the copy */ \
+ sc##_shift_by_ticks ( \
+ self->ts->sc##s[i], ticks, AO_UPDATE_THIS); \
+ }
+
+int
+move_chord_selections_action_do (
+ MoveChordSelectionsAction * self)
+{
+ int i;
+
+#define SHIFT_OBJ_POSITIVE(cc,sc) \
+ SHIFT_OBJ (cc, sc, self->ticks)
+
+ if (!self->first_call)
+ {
+ SHIFT_OBJ_POSITIVE (
+ ChordObject, chord_object);
+ }
+
+ EVENTS_PUSH (ET_CHORD_SELECTIONS_CHANGED,
+ NULL);
+
+ self->first_call = 0;
+
+ return 0;
+}
+
+int
+move_chord_selections_action_undo (
+ MoveChordSelectionsAction * self)
+{
+ int i;
+
+#define SHIFT_OBJ_NEGATIVE(cc,sc) \
+ SHIFT_OBJ (cc, sc, - self->ticks)
+
+ SHIFT_OBJ_NEGATIVE (
+ ChordObject, chord_object);
+
+ EVENTS_PUSH (ET_CHORD_SELECTIONS_CHANGED,
+ NULL);
+
+ return 0;
+}
+
+char *
+move_chord_selections_action_stringize (
+ MoveChordSelectionsAction * self)
+{
+ return g_strdup (
+ _("Move Chord(s)"));
+}
+
+void
+move_chord_selections_action_free (
+ MoveChordSelectionsAction * self)
+{
+ chord_selections_free (self->ts);
+
+ free (self);
+}
diff --git a/src/actions/move_timeline_selections_action.c b/src/actions/move_timeline_selections_action.c
index 90eba1d..15a6ebd 100644
--- a/src/actions/move_timeline_selections_action.c
+++ b/src/actions/move_timeline_selections_action.c
@@ -79,13 +79,9 @@ move_timeline_selections_action_do (
SHIFT_OBJ_POSITIVE (
Region, region);
SHIFT_OBJ_POSITIVE (
- ChordObject, chord_object);
- SHIFT_OBJ_POSITIVE (
ScaleObject, scale_object);
SHIFT_OBJ_POSITIVE (
Marker, marker);
- SHIFT_OBJ_POSITIVE (
- AutomationPoint, automation_point);
}
EVENTS_PUSH (ET_TL_SELECTIONS_CHANGED,
@@ -108,13 +104,9 @@ move_timeline_selections_action_undo (
SHIFT_OBJ_NEGATIVE (
Region, region);
SHIFT_OBJ_NEGATIVE (
- ChordObject, chord_object);
- SHIFT_OBJ_NEGATIVE (
ScaleObject, scale_object);
SHIFT_OBJ_NEGATIVE (
Marker, marker);
- SHIFT_OBJ_NEGATIVE (
- AutomationPoint, automation_point);
EVENTS_PUSH (ET_TL_SELECTIONS_CHANGED,
NULL);
diff --git a/src/audio/audio_region.c b/src/audio/audio_region.c
index 0ee1a30..8777977 100644
--- a/src/audio/audio_region.c
+++ b/src/audio/audio_region.c
@@ -41,6 +41,8 @@ audio_region_new (
AudioRegion * self =
calloc (1, sizeof (AudioRegion));
+ self->type = REGION_TYPE_AUDIO;
+
/* open with ad */
struct adinfo nfo;
SRC_DATA src_data;
@@ -61,7 +63,6 @@ audio_region_new (
/* init */
region_init ((Region *) self,
- REGION_TYPE_AUDIO,
start_pos,
&self->end_pos,
is_main);
diff --git a/src/audio/automation_curve.c b/src/audio/automation_curve.c
index b7f8264..402f352 100644
--- a/src/audio/automation_curve.c
+++ b/src/audio/automation_curve.c
@@ -24,7 +24,7 @@
#include "audio/automatable.h"
#include "audio/automation_curve.h"
-#include "audio/automation_track.h"
+#include "audio/automation_region.h"
#include "audio/channel.h"
#include "audio/port.h"
#include "audio/position.h"
@@ -45,29 +45,36 @@ automation_curve_init_loaded (
}
static AutomationCurve *
-_create_new (AutomationTrack * at,
- Position * pos)
+_create_new (
+ Region * region,
+ const Position * pos)
{
- AutomationCurve * ac = calloc (1, sizeof (AutomationCurve));
+ AutomationCurve * self =
+ calloc (1, sizeof (AutomationCurve));
- ac->at = at;
- position_set_to_pos (&ac->pos,
+ self->region = region;
+ position_set_to_pos (&self->pos,
pos);
- return ac;
+ return self;
}
/**
- * Creates curviness point in given track at given Position
+ * Creates an AutomationCurve.
+ *
+ * @param region The Region, used to figure out the
+ * AutomationCurve type.
*/
AutomationCurve *
-automation_curve_new (AutomationTrack * at,
- Position * pos)
+automation_curve_new (
+ Region * region,
+ const Position * pos)
{
- AutomationCurve * ac = _create_new (at, pos);
+ AutomationCurve * ac =
+ _create_new (region, pos);
ac->curviness = 1.f;
- switch (ac->at->automatable->type)
+ switch (ac->region->at->automatable->type)
{
case AUTOMATABLE_TYPE_PLUGIN_CONTROL:
case AUTOMATABLE_TYPE_CHANNEL_FADER:
@@ -86,51 +93,66 @@ automation_curve_new (AutomationTrack * at,
}
/**
- * Returns Y in pixels from the value based on the allocation of the
- * automation track.
+ * Returns Y in pixels from the value based on the
+ * allocation of the automation arranger.
*/
int
-automation_curve_get_y_in_px (AutomationCurve * ac)
+automation_curve_get_y_in_px (
+ AutomationCurve * ac)
{
AutomationPoint * prev_ap =
- automation_track_get_ap_before_curve (
- ac->at, ac);
- AutomationPoint * next_ap = automation_track_get_ap_after_curve (ac->at,
- ac);
+ automation_region_get_ap_before_curve (
+ ac->region, ac);
+ AutomationPoint * next_ap =
+ automation_region_get_ap_after_curve (
+ ac->region, ac);
+
/* ratio of current value in the range */
float ap_ratio;
if (ac->curviness >= AP_MID_CURVINESS)
{
- float ap_curviness_range = AP_MAX_CURVINESS - AP_MID_CURVINESS;
- ap_ratio = (ac->curviness - AP_MID_CURVINESS) / ap_curviness_range;
+ float ap_curviness_range =
+ AP_MAX_CURVINESS - AP_MID_CURVINESS;
+ ap_ratio =
+ (ac->curviness - AP_MID_CURVINESS) /
+ ap_curviness_range;
ap_ratio *= 0.5f; /* ratio is only for half */
ap_ratio += 0.5f; /* add the missing half */
}
else
{
- float ap_curviness_range = AP_MID_CURVINESS - AP_MIN_CURVINESS;
- ap_ratio = (ac->curviness - AP_MIN_CURVINESS) / ap_curviness_range;
+ float ap_curviness_range =
+ AP_MID_CURVINESS - AP_MIN_CURVINESS;
+ ap_ratio =
+ (ac->curviness - AP_MIN_CURVINESS) /
+ ap_curviness_range;
ap_ratio *= 0.5f; /* ratio is only for half */
}
- int prev_ap_y_pos = automation_point_get_y_in_px (prev_ap);
- int next_ap_y_pos = automation_point_get_y_in_px (next_ap);
+ int prev_ap_y_pos =
+ automation_point_get_y_in_px (prev_ap);
+ int next_ap_y_pos =
+ automation_point_get_y_in_px (next_ap);
int ap_max = MAX (prev_ap_y_pos, next_ap_y_pos);
int ap_min = MIN (prev_ap_y_pos, next_ap_y_pos);
int allocated_h = ap_max - ap_min;
int point = ap_max - ap_ratio * allocated_h;
+
return point;
}
/**
- * The function.
+ * TODO add description.
*
* See https://stackoverflow.com/questions/17623152/how-map-tween-a-number-based-on-a-dynamic-curve
+ * @param x X-coordinate.
+ * @param curviness Curviness variable.
+ * @param start_at_1 Start at lower point.
*/
double
automation_curve_get_y_normalized (
- double x, ///< x coordinate
+ double x,
double curviness,
- int start_at_1) ///< start at lower point
+ int start_at_1)
{
if (start_at_1)
{
@@ -149,45 +171,61 @@ automation_curve_get_y_normalized (
*
* See https://stackoverflow.com/questions/17623152/how-map-tween-a-number-based-on-a-dynamic-curve
*
- * FIXME should be on widget.
+ * @param ac The start point (0, 0).
+ * @param x X-coordinate in px.
+ * @param width Total width in px.
+ * @param height Total height in px.
*/
double
-automation_curve_get_y_px (AutomationCurve * ac, ///< start point (0, 0)
- double x, ///< x coordinate in px
- double width, ///< total width in px
- double height) ///< total height in px
+automation_curve_get_y_px (
+ AutomationCurve * ac,
+ double x,
+ double width,
+ double height)
{
/* find next curve ap & next value ap */
AutomationPoint * prev_ap =
- automation_track_get_ap_before_curve (
- ac->at,
- ac);
+ automation_region_get_ap_before_curve (
+ ac->region, ac);
AutomationPoint * next_ap =
- automation_track_get_ap_after_curve (
- ac->at,
- ac);
+ automation_region_get_ap_after_curve (
+ ac->region, ac);
double dx = x / width; /* normalized x */
double dy;
double ret;
- if (automation_point_get_y_in_px (next_ap) > /* if next point is lower */
+
+ /* if next point is lower */
+ if (automation_point_get_y_in_px (next_ap) >
automation_point_get_y_in_px (prev_ap))
{
- dy = automation_curve_get_y_normalized (dx, ac->curviness, 1); /* start higher */
+ /* start higher */
+ dy =
+ automation_curve_get_y_normalized (
+ dx, ac->curviness, 1);
ret = dy * height;
- return height - ret; /* reverse the value because in pixels higher y values
- are actually lower */
+
+ /* reverse the value because in pixels
+ * higher y values are actually lower */
+ return height - ret;
}
else
{
- dy = automation_curve_get_y_normalized (dx, ac->curviness, 0);
+ dy =
+ automation_curve_get_y_normalized (
+ dx, ac->curviness, 0);
ret = dy * height;
return - ret;
}
}
+/**
+ * Sets the curviness of the AutomationCurve.
+ */
void
-automation_curve_set_curviness (AutomationCurve * ac, float curviness)
+automation_curve_set_curviness (
+ AutomationCurve * ac,
+ float curviness)
{
if (ac->curviness == curviness)
return;
@@ -205,6 +243,7 @@ automation_curve_free (AutomationCurve * ac)
{
if (GTK_IS_WIDGET (ac->widget))
gtk_widget_destroy (GTK_WIDGET (ac->widget));
+
free (ac);
}
diff --git a/src/audio/automation_point.c b/src/audio/automation_point.c
index 7659f35..0936394 100644
--- a/src/audio/automation_point.c
+++ b/src/audio/automation_point.c
@@ -24,15 +24,18 @@
#include "audio/automatable.h"
#include "audio/automation_point.h"
+#include "audio/automation_region.h"
#include "audio/automation_track.h"
#include "audio/channel.h"
#include "audio/instrument_track.h"
#include "audio/port.h"
#include "audio/position.h"
#include "audio/track.h"
+#include "gui/widgets/automation_arranger.h"
#include "gui/widgets/automation_curve.h"
#include "gui/widgets/automation_point.h"
#include "gui/widgets/automation_track.h"
+#include "gui/widgets/center_dock.h"
#include "plugins/lv2_plugin.h"
#include "plugins/plugin.h"
#include "project.h"
@@ -45,7 +48,7 @@
ARRANGER_OBJ_DEFINE_MOVABLE (
AutomationPoint, automation_point,
- timeline_selections, TL_SELECTIONS);
+ automation_selections, AUTOMATION_SELECTIONS);
static AutomationPoint *
_create_new (
@@ -56,46 +59,38 @@ _create_new (
position_set_to_pos (
&ap->pos, pos);
- ap->track_pos = -1;
ap->index = -1;
- ap->at_index = -1;
return ap;
}
/**
- * Sets the AutomationTrack and the index in the
- * AutomationTrack that the AutomationPoint
+ * Sets the Region and the index in the
+ * region that the AutomationPoint
* belongs to, in all its counterparts.
*/
void
-automation_point_set_automation_track_and_index (
- AutomationPoint * _ap,
- AutomationTrack * at,
+automation_point_set_region_and_index (
+ AutomationPoint * ap,
+ Region * region,
int index)
{
- g_return_if_fail (at);
+ g_return_if_fail (region);
- AutomationPoint * ap;
- for (int i = 0; i < 4; i++)
+ for (int i = 0; i < 2; i++)
{
- if (i == 0)
- ap = automation_point_get_main_automation_point (_ap);
- else if (i == 1)
- ap = automation_point_get_main_trans_automation_point (_ap);
- else if (i == 2)
+ if (i == AOI_COUNTERPART_MAIN)
ap =
- (AutomationPoint *)
- _ap->obj_info.lane;
- else if (i == 3)
+ automation_point_get_main_automation_point (
+ ap);
+ else if (i == AOI_COUNTERPART_MAIN_TRANSIENT)
ap =
- (AutomationPoint *)
- _ap->obj_info.lane_trans;
+ automation_point_get_main_trans_automation_point (
+ ap);
- ap->at = at;
- ap->at_index = at->index;
+ ap->region = region;
+ ap->region_name = g_strdup (region->name);
ap->index = index;
- ap->track_pos = at->track->pos;
}
}
@@ -119,6 +114,16 @@ automation_point_is_equal (
}
/**
+ * Returns the Track this AutomationPoint is in.
+ */
+Track *
+automation_point_get_track (
+ AutomationPoint * ap)
+{
+ return ap->region->at->track;
+}
+
+/**
* Finds the automation point in the project matching
* the params of the given one.
*/
@@ -126,21 +131,18 @@ AutomationPoint *
automation_point_find (
AutomationPoint * src)
{
- g_warn_if_fail (
- src->track_pos > -1 &&
- src->at_index > -1 &&
- src->index > -1);
- Track * track =
- TRACKLIST->tracks[src->track_pos];
- AutomationTrack * at =
- track->automation_tracklist.ats[src->at_index];
- g_warn_if_fail (track && at);
+ g_warn_if_fail (src->region);
+
+ /* the src region might be an unused clone, find
+ * the actual region. */
+ Region * region =
+ region_find (src->region);
int i;
AutomationPoint * ap;
- for (i = 0; i < at->num_aps; i++)
+ for (i = 0; i < region->num_aps; i++)
{
- ap = at->aps[i];
+ ap = region->aps[i];
if (automation_point_is_equal (src, ap))
return ap;
}
@@ -192,9 +194,9 @@ automation_point_clone (
automation_point_new_float (
src->fvalue, &src->pos, is_main);
- if (src->at)
- automation_point_set_automation_track_and_index (
- ap, src->at, src->index);
+ if (src->region)
+ automation_point_set_region_and_index (
+ ap, src->region, src->index);
position_set_to_pos (
&ap->pos, &src->pos);
@@ -205,6 +207,8 @@ automation_point_clone (
/**
* Returns Y in pixels from the value based on the
* allocation of the automation track.
+ *
+ * FIXME move to widget.
*/
int
automation_point_get_y_in_px (
@@ -216,7 +220,7 @@ automation_point_get_y_in_px (
int allocated_h =
gtk_widget_get_allocated_height (
- GTK_WIDGET (self->at->widget));
+ GTK_WIDGET (MW_AUTOMATION_ARRANGER));
int point = allocated_h - ap_ratio * allocated_h;
return point;
}
@@ -228,25 +232,15 @@ float
automation_point_get_normalized_value (
AutomationPoint * self)
{
- g_warn_if_fail (self->at);
+ g_warn_if_fail (self->region->at);
/* TODO convert to macro */
return automatable_real_val_to_normalized (
- self->at->automatable,
+ self->region->at->automatable,
self->fvalue);
}
/**
- * Returns the Track this AutomationPoint is in.
- */
-Track *
-automation_point_get_track (
- AutomationPoint * ap)
-{
- return TRACKLIST->tracks[ap->track_pos];
-}
-
-/**
* Moves the AutomationPoint by the given amount of
* ticks.
*
@@ -270,12 +264,13 @@ automation_point_on_move (
AutomationPoint * ap = automation_point;
- /* FIXME */
/* get prev and next value APs */
AutomationPoint * prev_ap =
- automation_track_get_prev_ap (ap->at, ap);
+ automation_region_get_prev_ap (
+ ap->region, ap);
AutomationPoint * next_ap =
- automation_track_get_next_ap (ap->at, ap);
+ automation_region_get_next_ap (
+ ap->region, ap);
/* get adjusted pos for this automation point */
Position ap_pos;
@@ -296,8 +291,8 @@ automation_point_on_move (
position_get_midway_pos (
&prev_ap->pos, &ap_pos, &mid_pos);
ac =
- automation_track_get_next_curve_ac (
- ap->at, prev_ap);
+ automation_region_get_next_curve_ac (
+ ap->region, prev_ap);
position_set_to_pos (&ac->pos, &mid_pos);
/* set pos for ap */
@@ -314,8 +309,8 @@ automation_point_on_move (
position_get_midway_pos (
&ap_pos, &next_ap->pos, &mid_pos);
ac =
- automation_track_get_next_curve_ac (
- ap->at, ap);
+ automation_region_get_next_curve_ac (
+ ap->region, ap);
position_set_to_pos (&ac->pos, &mid_pos);
/* set pos for ap - if no prev ap exists
@@ -350,13 +345,13 @@ automation_point_update_fvalue (
AutomationPoint, self, fvalue, real_val,
update_flag);
- Automatable * a = self->at->automatable;
+ Automatable * a = self->region->at->automatable;
automatable_set_val_from_normalized (
a,
automatable_real_val_to_normalized (
a, real_val));
AutomationCurve * ac =
- self->at->acs[self->index];
+ self->region->acs[self->index];
if (ac && ac->widget)
ac->widget->cache = 0;
}
@@ -365,9 +360,14 @@ automation_point_update_fvalue (
* Destroys the widget and frees memory.
*/
void
-automation_point_free (AutomationPoint * ap)
+automation_point_free (
+ AutomationPoint * self)
{
- if (ap->widget)
- gtk_widget_destroy (GTK_WIDGET (ap->widget));
- free (ap);
+ if (GTK_IS_WIDGET (self->widget))
+ gtk_widget_destroy (GTK_WIDGET (self->widget));
+
+ if (self->region_name)
+ g_free (self->region_name);
+
+ free (self);
}
diff --git a/src/audio/automation_region.c b/src/audio/automation_region.c
new file mode 100644
index 0000000..84ffcdb
--- /dev/null
+++ b/src/audio/automation_region.c
@@ -0,0 +1,474 @@
+/*
+ * Copyright (C) 2019 Alexandros Theodotou <alex at zrythm dot org>
+ *
+ * This file is part of Zrythm
+ *
+ * Zrythm is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Zrythm 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 Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with Zrythm. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+#include <stdlib.h>
+
+#include "audio/automation_curve.h"
+#include "audio/automation_point.h"
+#include "audio/automation_region.h"
+#include "audio/position.h"
+#include "audio/region.h"
+#include "gui/backend/automation_selections.h"
+#include "gui/backend/events.h"
+#include "project.h"
+#include "utils/arrays.h"
+#include "utils/flags.h"
+#include "utils/objects.h"
+
+static int
+cmpfunc (const void * _a, const void * _b)
+{
+ AutomationPoint * a = *(AutomationPoint **)_a;
+ AutomationPoint * b = *(AutomationPoint **)_b;
+ int ret = position_compare (&a->pos,
+ &b->pos);
+ if (ret == 0 &&
+ a->index <
+ b->index)
+ {
+ return -1;
+ }
+
+ return ret;
+}
+
+static int
+cmpfunc_curve (const void * _a, const void * _b)
+{
+ AutomationCurve * a = *(AutomationCurve **)_a;
+ AutomationCurve * b = *(AutomationCurve **)_b;
+ int ret = position_compare (&a->pos,
+ &b->pos);
+ if (ret == 0 &&
+ a->index <
+ b->index)
+ {
+ return -1;
+ }
+
+ return ret;
+}
+
+Region *
+automation_region_new (
+ const Position * start_pos,
+ const Position * end_pos,
+ const int is_main)
+{
+ Region * self =
+ calloc (1, sizeof (Region));
+
+ self->type = REGION_TYPE_AUTOMATION;
+
+ self->aps_size = 2;
+ self->aps =
+ malloc (self->aps_size *
+ sizeof (AutomationPoint *));
+ self->aps =
+ malloc ((self->aps_size - 1) *
+ sizeof (AutomationPoint *));
+
+ region_init (
+ self, start_pos, end_pos, is_main);
+
+ return self;
+}
+
+/**
+ * Prints the automation in this Region.
+ */
+void
+automation_region_print_automation (
+ Region * self)
+{
+ AutomationPoint * ap;
+ for (int i = 0; i < self->num_aps; i++)
+ {
+ ap = self->aps[i];
+ g_message ("%d", i);
+ position_print (&ap->pos);
+ }
+}
+
+/**
+ * Forces sort of the automation points.
+ */
+void
+automation_region_force_sort (
+ Region * self)
+{
+ /* sort by position */
+ qsort (self->aps,
+ self->num_aps,
+ sizeof (AutomationPoint *),
+ cmpfunc);
+ qsort (self->acs,
+ self->num_acs,
+ sizeof (AutomationCurve *),
+ cmpfunc_curve);
+
+ /* refresh indices */
+ for (int i = 0;
+ i < self->num_acs;
+ i++)
+ self->acs[i]->index = i;
+
+ /* refresh indices */
+ for (int i = 0; i < self->num_aps; i++)
+ automation_point_set_region_and_index (
+ self->aps[i], self, i);
+}
+
+/**
+ * Adds the given AutomationCurve.
+ */
+void
+automation_region_add_ac (
+ Region * self,
+ AutomationCurve * ac)
+{
+ /** double array size if full */
+ if (self->num_acs == self->aps_size - 1)
+ {
+ self->aps_size *= 2;
+ self->acs =
+ realloc (
+ self->acs,
+ sizeof (AutomationCurve *) *
+ (self->aps_size - 1));
+ }
+
+ /* add point */
+ array_append (self->acs,
+ self->num_acs,
+ ac);
+
+ /* sort by position */
+ qsort (self->acs,
+ self->num_acs,
+ sizeof (AutomationCurve *),
+ cmpfunc_curve);
+
+ /* refresh indices */
+ for (int i = 0;
+ i < self->num_acs;
+ i++)
+ self->acs[i]->index = i;
+
+ EVENTS_PUSH (ET_AUTOMATION_CURVE_CREATED, ac);
+}
+
+static void
+create_curve_point_before (
+ Region * self,
+ AutomationPoint * prev_ap,
+ AutomationPoint * ap)
+{
+ Position mid_pos;
+
+ /* get midpoint between prev ap and current */
+ position_get_midway_pos (&prev_ap->pos,
+ &ap->pos,
+ &mid_pos);
+ g_warn_if_fail (
+ position_is_before_or_equal (
+ &mid_pos, &ap->pos));
+ g_warn_if_fail (
+ position_is_after_or_equal (
+ &mid_pos, &prev_ap->pos));
+
+ /* create curve point at mid pos */
+ AutomationCurve * curve =
+ automation_curve_new (self, &mid_pos);
+ automation_region_add_ac (self, curve);
+}
+
+static void
+create_curve_point_after (
+ Region * self,
+ AutomationPoint * next_ap,
+ AutomationPoint * ap)
+{
+ Position mid_pos;
+
+ /* get midpoint between prev ap and current */
+ position_get_midway_pos (&ap->pos,
+ &next_ap->pos,
+ &mid_pos);
+
+ /* create curve point at mid pos */
+ AutomationCurve * curve =
+ automation_curve_new (self, &mid_pos);
+ automation_region_add_ac (self, curve);
+}
+
+/**
+ * Adds automation point and optionally generates
+ * curve points accordingly.
+ *
+ * @param gen_curve_points Generate AutomationCurve's.
+ */
+void
+automation_region_add_ap (
+ Region * self,
+ AutomationPoint * ap,
+ int gen_curves)
+{
+ /* add point */
+ array_double_size_if_full (
+ self->aps, self->num_aps, self->aps_size,
+ AutomationPoint *);
+ array_append (
+ self->aps, self->num_aps, ap);
+
+ /* sort by position */
+ qsort (self->aps,
+ self->num_aps,
+ sizeof (AutomationPoint *),
+ cmpfunc);
+
+ /* refresh indices */
+ for (int i = 0; i < self->num_aps; i++)
+ automation_point_set_region_and_index (
+ self->aps[i], self, i);
+
+ if (gen_curves)
+ {
+ /* add midway automation curve to control
+ * curviness */
+ AutomationPoint * prev_ap =
+ automation_region_get_prev_ap (self, ap);
+ AutomationPoint * next_ap =
+ automation_region_get_next_ap (self, ap);
+ /* 4 cases */
+ if (!prev_ap && !next_ap) /* only ap */
+ {
+ /* do nothing */
+ }
+ else if (prev_ap && !next_ap) /* last ap */
+ {
+ create_curve_point_before (
+ self, prev_ap, ap);
+ }
+ else if (!prev_ap && next_ap) /* first ap */
+ {
+ create_curve_point_after (
+ self, next_ap, ap);
+ }
+ else /* has next & prev */
+ {
+ /* remove existing curve */
+ AutomationCurve * prev_curve =
+ automation_region_get_next_curve_ac (
+ self, prev_ap);
+ automation_region_remove_ac (
+ self, prev_curve, F_FREE);
+
+ create_curve_point_before (
+ self, prev_ap, ap);
+ create_curve_point_after (
+ self, next_ap, ap);
+ }
+ }
+
+ EVENTS_PUSH (ET_AUTOMATION_POINT_CREATED,
+ ap);
+}
+
+AutomationPoint *
+automation_region_get_ap_before_curve (
+ Region * self,
+ AutomationCurve * ac)
+{
+ if (ac && ac->index < self->num_aps)
+ return self->aps[ac->index];
+
+ return NULL;
+}
+
+/**
+ * Returns the ap after the curve point.
+ */
+AutomationPoint *
+automation_region_get_ap_after_curve (
+ Region * self,
+ AutomationCurve * ac)
+{
+ if (ac &&
+ ac->index < self->num_aps - 1)
+ return self->aps[ac->index + 1];
+
+ return NULL;
+}
+
+/**
+ * Returns the automation point before the position.
+ */
+AutomationPoint *
+automation_region_get_prev_ap (
+ Region * self,
+ AutomationPoint * ap)
+{
+ if (ap->index > 0)
+ return self->aps[ap->index - 1];
+
+ return NULL;
+}
+
+/**
+ * Returns the automation point after the position.
+ */
+AutomationPoint *
+automation_region_get_next_ap (
+ Region * self,
+ AutomationPoint * ap)
+{
+ if (ap && ap->index < self->num_aps - 1)
+ return self->aps[ap->index + 1];
+
+ return NULL;
+}
+
+/**
+ * Returns the curve point right after the given ap
+ */
+AutomationCurve *
+automation_region_get_next_curve_ac (
+ Region * self,
+ AutomationPoint * ap)
+{
+ /* if not last or only AP */
+ if (ap->index != self->num_aps - 1)
+ return self->acs[ap->index];
+
+ return NULL;
+}
+
+/**
+ * Removes the AutomationPoint from the Region,
+ * optionally freeing it.
+ */
+void
+automation_region_remove_ap (
+ Region * self,
+ AutomationPoint * ap,
+ int free)
+{
+ /* deselect */
+ automation_selections_remove_automation_point (
+ AUTOMATION_SELECTIONS, ap);
+
+ /* remove the curves first */
+ AutomationPoint * prev_ap =
+ automation_region_get_prev_ap (self, ap);
+ AutomationPoint * next_ap =
+ automation_region_get_next_ap (self, ap);
+
+ AutomationCurve * ac;
+ /* 4 cases */
+ if (!prev_ap && !next_ap) /* only ap */
+ {
+ /* do nothing */
+ }
+ else if (prev_ap && !next_ap) /* last ap */
+ {
+ /* remove curve before */
+ ac =
+ automation_region_get_next_curve_ac (
+ self, prev_ap);
+ automation_region_remove_ac (self, ac, F_FREE);
+ }
+ else if (!prev_ap && next_ap) /* first ap */
+ {
+ /* remove curve after */
+ ac =
+ automation_region_get_next_curve_ac (
+ self, ap);
+ automation_region_remove_ac (self, ac, F_FREE);
+ }
+ else /* has next & prev */
+ {
+ /* remove curve before and after, and add
+ * a new curve at this ap's pos */
+ ac =
+ automation_region_get_next_curve_ac (
+ self, prev_ap);
+ automation_region_remove_ac (self, ac, F_FREE);
+ ac =
+ automation_region_get_next_curve_ac (
+ self, ap);
+ automation_region_remove_ac (self, ac, F_FREE);
+
+ create_curve_point_before (
+ self, prev_ap, next_ap);
+ }
+
+ array_delete (self->aps,
+ self->num_aps,
+ ap);
+
+
+ if (free)
+ free_later (ap, automation_point_free);
+
+ EVENTS_PUSH (ET_AUTOMATION_POINT_REMOVED, NULL);
+}
+
+/**
+ * Removes the AutomationCurve from the Region,
+ * optionally freeing it.
+ */
+void
+automation_region_remove_ac (
+ Region * self,
+ AutomationCurve * ac,
+ int free)
+{
+ array_delete (self->acs,
+ self->num_acs,
+ ac);
+ g_warn_if_fail (ac);
+ if (free)
+ free_later (
+ ac, automation_curve_free);
+
+ EVENTS_PUSH (ET_AUTOMATION_CURVE_REMOVED, NULL);
+}
+
+/**
+ * Frees members only but not the Region itself.
+ *
+ * Regions should be free'd using region_free.
+ */
+void
+automation_region_free_members (
+ Region * self)
+{
+ int i;
+ for (i = 0; i < self->num_aps; i++)
+ automation_region_remove_ap (
+ self, self->aps[i], F_FREE);
+
+ for (i = 0; i < self->num_acs; i++)
+ automation_region_remove_ac (
+ self, self->acs[i], F_FREE);
+
+ free (self->aps);
+ free (self->acs);
+}
diff --git a/src/audio/automation_track.c b/src/audio/automation_track.c
index d09a6e4..9ef20e4 100644
--- a/src/audio/automation_track.c
+++ b/src/audio/automation_track.c
@@ -23,6 +23,7 @@
#include "audio/automation_curve.h"
#include "audio/automation_track.h"
#include "audio/automation_point.h"
+#include "audio/automation_region.h"
#include "audio/instrument_track.h"
#include "audio/track.h"
#include "gui/backend/events.h"
@@ -49,467 +50,45 @@ automation_track_new (Automatable * a)
{
g_warn_if_fail (a->track);
- AutomationTrack * at =
+ AutomationTrack * self =
calloc (1, sizeof (AutomationTrack));
- at->track = a->track;
- g_message ("new automation track for %s (pos %d)",
- a->track->name, a->track->pos);
- at->automatable = a;
+ self->track = a->track;
+ self->automatable = a;
- return at;
-}
-
-static int
-cmpfunc (const void * _a, const void * _b)
-{
- AutomationPoint * a = *(AutomationPoint **)_a;
- AutomationPoint * b = *(AutomationPoint **)_b;
- int ret = position_compare (&a->pos,
- &b->pos);
- if (ret == 0 &&
- a->index <
- b->index)
- {
- return -1;
- }
-
- return ret;
-}
-
-static int
-cmpfunc_curve (const void * _a, const void * _b)
-{
- AutomationCurve * a = *(AutomationCurve **)_a;
- AutomationCurve * b = *(AutomationCurve **)_b;
- int ret = position_compare (&a->pos,
- &b->pos);
- if (ret == 0 &&
- a->index <
- b->index)
- {
- return -1;
- }
+ self->regions_size = 1;
+ self->regions =
+ malloc (self->regions_size *
+ sizeof (Region *));
- return ret;
+ return self;
}
/**
- * Adds and shows curve point at pos.
+ * Adds an automation Region to the AutomationTrack.
*/
-static void
-add_and_show_curve_point (AutomationTrack * at,
- Position * pos)
-{
- /* create curve point at mid pos */
- AutomationCurve * curve =
- automation_curve_new (at, pos);
- automation_track_add_ac (at, curve);
-
- /* FIXME these should be in gui code */
- gtk_overlay_add_overlay (
- GTK_OVERLAY (MW_TIMELINE),
- GTK_WIDGET (curve->widget));
- gtk_widget_show (GTK_WIDGET (curve->widget));
-}
-
-static void
-create_curve_point_before (
- AutomationTrack * at,
- AutomationPoint * prev_ap,
- AutomationPoint * ap)
-{
- Position mid_pos;
-
- /* get midpoint between prev ap and current */
- position_get_midway_pos (&prev_ap->pos,
- &ap->pos,
- &mid_pos);
- g_warn_if_fail (position_compare (&mid_pos,
- &ap->pos) <= 0);
- g_warn_if_fail (position_compare (&mid_pos,
- &prev_ap->pos) >= 0);
-
- add_and_show_curve_point (at, &mid_pos);
-}
-
-static void
-create_curve_point_after (AutomationTrack * at,
- AutomationPoint * next_ap,
- AutomationPoint * ap)
-{
- Position mid_pos;
-
- /* get midpoint between current ap and next */
- position_get_midway_pos (&ap->pos,
- &next_ap->pos,
- &mid_pos);
-
- add_and_show_curve_point (at, &mid_pos);
-}
-
void
-automation_track_print_automation_points (AutomationTrack * at)
-{
- for (int i = 0; i < at->num_aps; i++)
- {
- AutomationPoint * ap = at->aps[i];
- g_message ("%d", i);
- position_print (&ap->pos);
- }
-}
-
-void
-automation_track_force_sort (AutomationTrack * at)
-{
- /* sort by position */
- qsort (at->aps,
- at->num_aps,
- sizeof (AutomationPoint *),
- cmpfunc);
- qsort (at->acs,
- at->num_acs,
- sizeof (AutomationCurve *),
- cmpfunc_curve);
-
- /* refresh indices */
- for (int i = 0;
- i < at->num_acs;
- i++)
- at->acs[i]->index = i;
-
- /* refresh indices */
- for (int i = 0; i < at->num_aps; i++)
- automation_point_set_automation_track_and_index (
- at->aps[i], at, i);
-}
-
-/**
- * Adds automation curve.
- */
-void
-automation_track_add_ac (
- AutomationTrack * at,
- AutomationCurve * ac)
-{
- /* add point */
- array_append (at->acs,
- at->num_acs,
- ac);
-
- /* sort by position */
- qsort (at->acs,
- at->num_acs,
- sizeof (AutomationCurve *),
- cmpfunc_curve);
-
- /* refresh indices */
- for (int i = 0;
- i < at->num_acs;
- i++)
- at->acs[i]->index = i;
-
- EVENTS_PUSH (ET_AUTOMATION_CURVE_CREATED, ac);
-}
-
-/**
- * Adds automation point and optionally generates curve points accordingly.
- */
-void
-automation_track_add_ap (
- AutomationTrack * at,
- AutomationPoint * ap,
- int gen_widget,
- int generate_curve_points)
-{
- /* add point */
- array_append (at->aps,
- at->num_aps,
- ap);
-
- /* sort by position */
- qsort (at->aps,
- at->num_aps,
- sizeof (AutomationPoint *),
- cmpfunc);
-
- /* refresh indices */
- for (int i = 0; i < at->num_aps; i++)
- automation_point_set_automation_track_and_index (
- at->aps[i], at, i);
-
- g_warn_if_fail (ap->at);
-
- if (generate_curve_points)
- {
- /* add midway automation curve to control
- * curviness */
- AutomationPoint * prev_ap =
- automation_track_get_prev_ap (at,
- ap);
- AutomationPoint * next_ap =
- automation_track_get_next_ap (at,
- ap);
- /* 4 cases */
- if (!prev_ap && !next_ap) /* only ap */
- {
- /* do nothing */
- }
- else if (prev_ap && !next_ap) /* last ap */
- {
- create_curve_point_before (at,
- prev_ap,
- ap);
- }
- else if (!prev_ap && next_ap) /* first ap */
- {
- create_curve_point_after (at,
- next_ap,
- ap);
- }
- else /* has next & prev */
- {
- /* remove existing curve */
- AutomationCurve * prev_curve =
- automation_track_get_next_curve_ac (
- at, prev_ap);
- automation_track_remove_ac (
- at, prev_curve);
-
- create_curve_point_before (
- at, prev_ap, ap);
- create_curve_point_after (
- at, next_ap, ap);
- }
- }
-
- if (gen_widget)
- automation_point_gen_widget (ap);
-
- EVENTS_PUSH (ET_AUTOMATION_POINT_CREATED,
- ap);
-}
-
-AutomationPoint *
-automation_track_get_ap_before_curve (
- AutomationTrack * at,
- AutomationCurve * ac)
-{
- if (ac && ac->index < at->num_aps)
- return at->aps[ac->index];
-
- return NULL;
-
- /*for (int i = at->num_automation_points - 1; i >= 0; i--)*/
- /*{*/
- /*AutomationPoint * ap = at->automation_points[i];*/
- /*if (position_compare (&ac->pos,*/
- /*&ap->pos) >= 0)*/
- /*{*/
- /*return ap;*/
- /*}*/
- /*}*/
- /*return NULL;*/
-}
-
-/**
- * Returns the ap after the curve point.
- */
-AutomationPoint *
-automation_track_get_ap_after_curve (
- AutomationTrack * at,
- AutomationCurve * ac)
-{
- if (ac &&
- ac->index < at->num_aps - 1)
- return at->aps[ac->index + 1];
-
- return NULL;
-
- /*for (int i = 0; i < at->num_automation_points; i++)*/
- /*{*/
- /*AutomationPoint * ap = at->automation_points[i];*/
- /*if (position_compare (&ap->pos,*/
- /*&ac->pos) >= 0)*/
- /*{*/
- /*return ap;*/
- /*}*/
- /*}*/
- /*return NULL;*/
-}
-
-/**
- * Returns the automation point before the position.
- */
-AutomationPoint *
-automation_track_get_prev_ap (AutomationTrack * at,
- AutomationPoint * _ap)
-{
- /*int index = automation_track_get_ap_index (at, _ap);*/
- /*g_warn_if_fail (index > -1);*/
- /*for (int i = index - 1; i >= 0; i--)*/
- /*{*/
- /*AutomationPoint * ap = at->automation_points[i];*/
- /*if (position_compare (&_ap->pos,*/
- /*&ap->pos) >= 0)*/
- /*{*/
- /*return ap;*/
- /*}*/
- /*}*/
-
- if (_ap->index > 0)
- return at->aps[_ap->index - 1];
-
- return NULL;
-}
-
-/**
- * Returns the automation point after the position.
- */
-AutomationPoint *
-automation_track_get_next_ap (
- AutomationTrack * at,
- AutomationPoint * _ap)
-{
- /*int index = automation_track_get_ap_index (at, _ap);*/
- /*g_warn_if_fail (index > -1);*/
- /*for (int i = index + 1; i < at->num_automation_points; i++)*/
- /*{*/
- /*AutomationPoint * ap = at->automation_points[i];*/
- /*if (position_compare (&ap->pos,*/
- /*&_ap->pos) >= 0)*/
- /*{*/
- /*return ap;*/
- /*}*/
- /*}*/
- if (_ap &&
- _ap->index < at->num_aps - 1)
- return at->aps[_ap->index + 1];
-
- return NULL;
-}
-
-/**
- * Returns the curve point right after the given ap
- */
-AutomationCurve *
-automation_track_get_next_curve_ac (
- AutomationTrack * at,
- AutomationPoint * ap)
-{
- /*int index = automation_track_get_ap_index (at, ap);*/
-
- /* if not last or only AP */
- if (ap->index != at->num_aps - 1)
- return at->acs[ap->index];
-
- return NULL;
-}
-
-/**
- * Removes automation point from automation track.
- */
-void
-automation_track_remove_ap (
- AutomationTrack * at,
- AutomationPoint * ap,
- int free)
-{
- /* deselect */
- timeline_selections_remove_automation_point (
- TL_SELECTIONS, ap);
-
- /* remove the curves first */
- AutomationPoint * prev_ap =
- automation_track_get_prev_ap (at, ap);
- AutomationPoint * next_ap =
- automation_track_get_next_ap (at, ap);
-
- AutomationCurve * ac;
- /* 4 cases */
- if (!prev_ap && !next_ap) /* only ap */
- {
- /* do nothing */
- }
- else if (prev_ap && !next_ap) /* last ap */
- {
- /* remove curve before */
- ac =
- automation_track_get_next_curve_ac (
- at, prev_ap);
- automation_track_remove_ac (at, ac);
- g_message ("removed prev ac num acs %d",
- at->num_acs);
- }
- else if (!prev_ap && next_ap) /* first ap */
- {
- /* remove curve after */
- ac =
- automation_track_get_next_curve_ac (
- at, ap);
- automation_track_remove_ac (at, ac);
- }
- else /* has next & prev */
- {
- /* remove curve before and after, and add
- * a new curve at this ap's pos */
- ac =
- automation_track_get_next_curve_ac (
- at, prev_ap);
- automation_track_remove_ac (at, ac);
- ac =
- automation_track_get_next_curve_ac (
- at, ap);
- automation_track_remove_ac (at, ac);
-
- create_curve_point_before (
- at, prev_ap, next_ap);
- }
-
- array_delete (at->aps,
- at->num_aps,
- ap);
-
-
- if (free)
- free_later (ap, automation_point_free);
-
- EVENTS_PUSH (ET_AUTOMATION_POINT_REMOVED, at);
-}
-
-/**
- * Removes automation point from automation track.
- */
-void
-automation_track_remove_ac (AutomationTrack * at,
- AutomationCurve * ac)
+automation_track_add_region (
+ AutomationTrack * self,
+ Region * region)
{
- array_delete (at->acs,
- at->num_acs,
- ac);
- g_warn_if_fail (ac);
- free_later (ac,
- automation_curve_free);
-
- EVENTS_PUSH (ET_AUTOMATION_CURVE_REMOVED, at);
+ g_return_if_fail (
+ region->type == REGION_TYPE_AUTOMATION);
+
+ array_double_size_if_full (
+ self->regions, self->num_regions,
+ self->regions_size, Region *);
+ array_append (self->regions,
+ self->num_regions,
+ region);
}
-/*int*/
-/*automation_track_get_ap_index (AutomationTrack * at,*/
- /*AutomationPoint * ap)*/
-/*{*/
- /*for (int i = 0; i < at->num_automation_points; i++)*/
- /*{*/
- /*if (at->automation_points[i] == ap)*/
- /*{*/
- /*return i;*/
- /*}*/
- /*}*/
- /*return -1;*/
-/*}*/
/**
* Returns the automation curve at the given pos.
+ *
+ * This is supposed to be global so it belongs here
+ * instead of the automation Region.
*/
AutomationCurve *
automation_track_get_ac_at_pos (
@@ -522,75 +101,66 @@ automation_track_get_ac_at_pos (
if (!prev_ap)
return NULL;
AutomationPoint * next_ap =
- automation_track_get_next_ap (
- self, prev_ap);
+ automation_region_get_next_ap (
+ prev_ap->region, prev_ap);
if (!next_ap)
return NULL;
- return automation_track_get_next_curve_ac (
- self,
- prev_ap);
+
+ return
+ automation_region_get_next_curve_ac (
+ next_ap->region, prev_ap);
}
/**
- * Returns the automation point before the pos.
+ * Returns the last Region before the given
+ * Position.
+ */
+Region *
+automation_track_get_region_before_pos (
+ const AutomationTrack * self,
+ const Position * pos)
+{
+ Region * region;
+ for (int i = 0; i < self->num_regions; i++)
+ {
+ region = self->regions[i];
+
+ if (position_is_before_or_equal (
+ &region->start_pos, pos) &&
+ position_is_after_or_equal (
+ &region->end_pos, pos))
+ return region;
+ }
+ return NULL;
+}
+
+/**
+ * Returns the automation point before the Position
+ * on the timeline.
*/
AutomationPoint *
automation_track_get_ap_before_pos (
- AutomationTrack * self,
- Position * pos)
+ const AutomationTrack * self,
+ const Position * pos)
{
- AutomationPoint * ap;
+ Region * r =
+ automation_track_get_region_before_pos (
+ self, pos);
- /*for (int i = self->num_automation_points - 1;*/
- /*i >= 0;*/
- /*i--)*/
- /*{*/
- /*ap = self->automation_points[i];*/
- /*if (position_compare (&ap->pos,*/
- /*pos) <= 0)*/
- /*return ap;*/
- /*}*/
- /*return NULL;*/
-
- /* binary search */
- int first = 0;
- /*g_message ("num autom %d",*/
- /*self->num_automation_points);*/
- int last = self->num_aps - 1;
- if (first == last)
- return NULL;
- int middle = (first+last)/2;
- AutomationPoint * next_ap;
- int ap_is_before, next_ap_is_before;
+ Position local_pos;
+ region_timeline_pos_to_local (
+ r, pos, &local_pos, 1);
- while (first <= last)
+ AutomationPoint * ap;
+ for (int i = r->num_aps - 1; i >= 0; i--)
{
- ap = self->aps[middle];
- next_ap = NULL;
- next_ap_is_before = 0;
- if (middle < last)
- {
- next_ap =
- self->aps[middle + 1];
- next_ap_is_before =
- position_compare (
- &next_ap->pos, pos) <= 0;
- }
- ap_is_before =
- position_compare (
- &ap->pos, pos) <= 0;
-
- /* if both too early, look in the 2nd half*/
- if (ap_is_before && (
- next_ap_is_before))
- first = middle + 1;
- else if (ap_is_before)
+ ap = r->aps[i];
+
+ if (position_is_before_or_equal (
+ &ap->pos, &local_pos))
return ap;
- else
- last = middle - 1;
+ }
- middle = (first + last)/2;
- }
return NULL;
}
@@ -619,8 +189,8 @@ automation_track_get_normalized_val_at_pos (
return -1.f;
AutomationPoint * next_ap =
- automation_track_get_next_ap (
- self, prev_ap);
+ automation_region_get_next_ap (
+ prev_ap->region, prev_ap);
/*g_message ("prev fvalue %f next %f",*/
/*prev_ap->fvalue,*/
/*next_ap->fvalue);*/
@@ -671,19 +241,58 @@ automation_track_get_normalized_val_at_pos (
return result;
}
-/*int*/
-/*automation_track_get_curve_index (AutomationTrack * at,*/
- /*AutomationCurve * ac)*/
-/*{*/
- /*for (int i = 0; i < at->num_automation_curves; i++)*/
- /*{*/
- /*if (at->automation_curves[i] == ac)*/
- /*{*/
- /*return i;*/
- /*}*/
- /*}*/
- /*return -1;*/
-/*}*/
+/**
+ * Gets the last Region in the AutomationTrack.
+ */
+Region *
+automation_track_get_last_region (
+ AutomationTrack * self)
+{
+ Position pos;
+ position_init (&pos);
+ Region * region, * last_region = NULL;
+ for (int i = 0; i < self->num_regions; i++)
+ {
+ region = self->regions[i];
+
+ if (position_is_after (
+ &region->end_pos, &pos))
+ {
+ last_region = region;
+ position_set_to_pos (
+ &pos, &region->end_pos);
+ }
+ }
+ return last_region;
+}
+
+/**
+ * Clones the AutomationTrack.
+ */
+AutomationTrack *
+automation_track_clone (
+ AutomationTrack * src)
+{
+ AutomationTrack * dest =
+ calloc (1, sizeof (AutomationTrack));
+
+ dest->regions_size = src->num_regions;
+ dest->num_regions = src->num_regions;
+ dest->regions =
+ malloc (dest->regions_size *
+ sizeof (Region *));
+
+ Region * src_region;
+ for (int j = 0; j < src->num_regions; j++)
+ {
+ src_region = src->regions[j];
+ dest->regions[j] =
+ region_clone (
+ src_region, REGION_CLONE_COPY_MAIN);
+ }
+
+ return dest;
+}
void
automation_track_free (AutomationTrack * self)
@@ -691,14 +300,5 @@ automation_track_free (AutomationTrack * self)
if (self->widget && GTK_IS_WIDGET (self->widget))
gtk_widget_destroy (GTK_WIDGET (self->widget));
- int i;
- for (i = 0; i < self->num_aps; i++)
- automation_track_remove_ap (
- self, self->aps[i], F_FREE);
-
- for (i = 0; i < self->num_acs; i++)
- automation_track_remove_ac (
- self, self->acs[i]);
-
free (self);
}
diff --git a/src/audio/automation_tracklist.c b/src/audio/automation_tracklist.c
index b522c6f..957e5ba 100644
--- a/src/audio/automation_tracklist.c
+++ b/src/audio/automation_tracklist.c
@@ -278,37 +278,19 @@ automation_tracklist_clone (
AutomationTracklist * src,
AutomationTracklist * dest)
{
- AutomationTrack * src_at, * dest_at;
- AutomationPoint * src_ap, * dest_ap;
- AutomationCurve * src_ac, * dest_ac;
- int i, j;
+ AutomationTrack * src_at;
+ dest->ats_size = src->num_ats;
+ dest->num_ats = src->num_ats;
+ dest->ats =
+ malloc (dest->ats_size *
+ sizeof (AutomationTrack *));
+ int i;
for (i = 0; i < src->num_ats; i++)
{
src_at = src->ats[i];
- dest_at = dest->ats[i];
-
- /* add automation points */
- for (j = 0; j < src_at->num_aps; j++)
- {
- src_ap = src_at->aps[j];
- dest_ap =
- automation_point_new_float (
- src_ap->fvalue,
- &src_ap->pos, F_MAIN);
- automation_track_add_ap (
- dest_at, dest_ap, F_GEN_WIDGET, 0);
- }
-
- /* add automation curves */
- for (j = 0; j < src_at->num_acs; j++)
- {
- src_ac = src_at->acs[j];
- dest_ac =
- automation_curve_new (
- dest_at, &src_ac->pos);
- automation_track_add_ac (
- dest_at, dest_ac);
- }
+ dest->ats[i] =
+ automation_track_clone (
+ src_at);
}
/* TODO create same automation lanes */
diff --git a/src/audio/channel.c b/src/audio/channel.c
index a64f329..4d77ea4 100644
--- a/src/audio/channel.c
+++ b/src/audio/channel.c
@@ -49,6 +49,7 @@
#include "utils/flags.h"
#include "utils/math.h"
#include "utils/objects.h"
+#include "utils/stoat.h"
#include <gtk/gtk.h>
@@ -889,7 +890,7 @@ disconnect_prev_next (
* The MidiEvents are already dequeued at this
* point.
*/
-__attribute__((annotate("realtime")))
+REALTIME
void
channel_handle_recording (Channel * self)
{
@@ -945,7 +946,7 @@ channel_handle_recording (Channel * self)
ev->note_pitch,
ev->velocity, 1);
midi_region_add_midi_note (
- mr, mn, F_GEN_WIDGET);
+ mr, mn);
/* add to unended notes */
array_append (
diff --git a/src/audio/chord_object.c b/src/audio/chord_object.c
index 14f2f36..b820fd2 100644
--- a/src/audio/chord_object.c
+++ b/src/audio/chord_object.c
@@ -33,8 +33,8 @@
DEFINE_START_POS;
ARRANGER_OBJ_DEFINE_MOVABLE (
- ChordObject, chord_object, timeline_selections,
- TL_SELECTIONS);
+ ChordObject, chord_object, chord_selections,
+ CHORD_SELECTIONS);
/**
* Init the ChordObject after the Project is loaded.
@@ -97,13 +97,17 @@ ChordObject *
chord_object_find (
ChordObject * clone)
{
- for (int i = 0;
- i < P_CHORD_TRACK->num_chords; i++)
+ /* get actual region - clone's region might be
+ * an unused clone */
+ Region *r = region_find (clone->region);
+
+ ChordObject * chord;
+ for (int i = 0; i < r->num_chord_objects; i++)
{
+ chord = r->chord_objects[i];
if (chord_object_is_equal (
- P_CHORD_TRACK->chords[i],
- clone))
- return P_CHORD_TRACK->chords[i];
+ chord, clone))
+ return chord;
}
return NULL;
}
@@ -111,18 +115,24 @@ chord_object_find (
/**
* Finds the ChordObject in the project
* corresponding to the given one's position.
+ *
+ * Used in actions.
*/
ChordObject *
chord_object_find_by_pos (
ChordObject * clone)
{
- for (int i = 0;
- i < P_CHORD_TRACK->num_chords; i++)
+ /* get actual region - clone's region might be
+ * an unused clone */
+ Region *r = region_find (clone->region);
+
+ ChordObject * chord;
+ for (int i = 0; i < r->num_chord_objects; i++)
{
+ chord = r->chord_objects[i];
if (position_is_equal (
- &P_CHORD_TRACK->chords[i]->pos,
- &clone->pos))
- return P_CHORD_TRACK->chords[i];
+ &chord->pos, &clone->pos))
+ return chord;
}
return NULL;
}
@@ -154,35 +164,47 @@ chord_object_clone (
* Sets the Track of the chord.
*/
void
-chord_object_set_track (
+chord_object_set_region (
ChordObject * self,
- Track * track)
+ Region * region)
{
- self->track = track;
- self->track_pos = track->pos;
+ ChordObject * co;
+ for (int i = 0; i < 2; i++)
+ {
+ if (i == AOI_COUNTERPART_MAIN)
+ co =
+ chord_object_get_main_chord_object (
+ self);
+ else if (i == AOI_COUNTERPART_MAIN_TRANSIENT)
+ co =
+ chord_object_get_main_trans_chord_object (
+ self);
+
+ co->region = region;
+ co->region_name = g_strdup (region->name);
+ }
}
-
ARRANGER_OBJ_DEFINE_GEN_WIDGET_LANELESS (
ChordObject, chord_object);
/**
- * Returns the Track this ChordObject is in.
- */
-Track *
-chord_object_get_track (
- ChordObject * self)
-{
- return TRACKLIST->tracks[self->track_pos];
-}
-
-/**
* Frees the ChordObject.
*/
void
chord_object_free (
ChordObject * self)
{
+ if (self->widget)
+ {
+ gtk_widget_destroy (
+ GTK_WIDGET (self->widget));
+ }
+
chord_descriptor_free (self->descr);
+
+ if (self->region_name)
+ g_free (self->region_name);
+
free (self);
}
diff --git a/src/audio/chord_region.c b/src/audio/chord_region.c
new file mode 100644
index 0000000..b039312
--- /dev/null
+++ b/src/audio/chord_region.c
@@ -0,0 +1,121 @@
+/*
+ * Copyright (C) 2019 Alexandros Theodotou <alex at zrythm dot org>
+ *
+ * This file is part of Zrythm
+ *
+ * Zrythm is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Zrythm 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 Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with Zrythm. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+#include "audio/chord_region.h"
+#include "audio/chord_object.h"
+#include "gui/backend/events.h"
+#include "project.h"
+#include "utils/arrays.h"
+#include "utils/flags.h"
+#include "utils/objects.h"
+
+#include <glib/gi18n.h>
+
+/**
+ * Creates a new Region for chords.
+ *
+ * @param is_main If this is 1 it
+ * will create the additional Region (
+ * main_transient).
+ */
+Region *
+chord_region_new (
+ const Position * start_pos,
+ const Position * end_pos,
+ const int is_main)
+{
+ Region * self =
+ calloc (1, sizeof (Region));
+
+ self->chord_objects_size = 1;
+ self->chord_objects =
+ malloc (self->chord_objects_size *
+ sizeof (ChordObject *));
+ self->chord_objects =
+ malloc ((self->chord_objects_size - 1) *
+ sizeof (ChordObject *));
+
+ region_init (
+ self, start_pos, end_pos, is_main);
+
+ return self;
+}
+
+/**
+ * Adds a ChordObject to the Region.
+ */
+void
+chord_region_add_chord_object (
+ Region * self,
+ ChordObject * chord)
+{
+ array_double_size_if_full (
+ self->chord_objects, self->num_chord_objects,
+ self->chord_objects_size, ChordObject *);
+ array_append (
+ self->chord_objects, self->num_chord_objects,
+ chord);
+
+ chord_object_set_region (chord, self);
+
+ EVENTS_PUSH (ET_CHORD_OBJECT_CREATED, chord);
+}
+
+/**
+ * Removes a ChordObject from the Region.
+ *
+ * @param free Optionally free the ChordObject.
+ */
+void
+chord_region_remove_chord_object (
+ Region * self,
+ ChordObject * chord,
+ int free)
+{
+ /* deselect */
+ chord_selections_remove_chord_object (
+ CHORD_SELECTIONS, chord);
+
+ array_delete (self->chord_objects,
+ self->num_chord_objects,
+ chord);
+
+
+ if (free)
+ free_later (chord, chord_object_free);
+
+ EVENTS_PUSH (ET_CHORD_OBJECT_REMOVED, NULL);
+}
+
+/**
+ * Frees members only but not the Region itself.
+ *
+ * Regions should be free'd using region_free.
+ */
+void
+chord_region_free_members (
+ Region * self)
+{
+ int i;
+ for (i = 0; i < self->num_chord_objects; i++)
+ chord_region_remove_chord_object (
+ self, self->chord_objects[i], F_FREE);
+
+ free (self->chord_objects);
+}
diff --git a/src/audio/chord_track.c b/src/audio/chord_track.c
index 72ab9aa..0011bcd 100644
--- a/src/audio/chord_track.c
+++ b/src/audio/chord_track.c
@@ -49,37 +49,6 @@ chord_track_new ()
}
/**
- * Adds a chord to the chord track.
- */
-void
-chord_track_add_chord (
- ChordTrack * track,
- ChordObject * chord,
- int gen_widget)
-{
- g_warn_if_fail (
- track->type == TRACK_TYPE_CHORD && chord);
- g_warn_if_fail (
- chord->obj_info.counterpart ==
- AOI_COUNTERPART_MAIN);
- g_warn_if_fail (
- chord->obj_info.main &&
- chord->obj_info.main_trans &&
- chord->obj_info.lane &&
- chord->obj_info.lane_trans);
-
- chord_object_set_track (chord, track);
- array_append (track->chords,
- track->num_chords,
- chord);
-
- if (gen_widget)
- chord_object_gen_widget (chord);
-
- EVENTS_PUSH (ET_CHORD_OBJECT_CREATED, chord);
-}
-
-/**
* Adds a ChordObject to the Track.
*
* @param gen_widget Create a widget for the chord.
@@ -87,8 +56,7 @@ chord_track_add_chord (
void
chord_track_add_scale (
ChordTrack * track,
- ScaleObject * scale,
- int gen_widget)
+ ScaleObject * scale)
{
g_warn_if_fail (
track->type == TRACK_TYPE_CHORD && scale);
@@ -102,13 +70,13 @@ chord_track_add_scale (
scale->obj_info.lane_trans);
scale_object_set_track (scale, track);
+ array_double_size_if_full (
+ track->scales, track->num_scales,
+ track->scales_size, ScaleObject *);
array_append (track->scales,
track->num_scales,
scale);
- if (gen_widget)
- scale_object_gen_widget (scale);
-
EVENTS_PUSH (ET_SCALE_OBJECT_CREATED, scale);
}
@@ -141,10 +109,15 @@ chord_track_get_chord_at_pos (
const Track * ct,
const Position * pos)
{
+ Region * region =
+ track_get_region_at_pos (ct, pos);
+
ChordObject * chord = NULL;
- for (int i = ct->num_chords - 1; i >= 0; i--)
+ int i;
+ for (i = region->num_chord_objects - 1;
+ i >= 0; i--)
{
- chord = ct->chords[i];
+ chord = region->chord_objects[i];
if (position_is_before_or_equal (
&chord->pos, pos))
return chord;
@@ -153,29 +126,6 @@ chord_track_get_chord_at_pos (
}
/**
- * Removes a chord from the chord Track.
- */
-void
-chord_track_remove_chord (
- ChordTrack * self,
- ChordObject * chord,
- int free)
-{
- /* deselect */
- timeline_selections_remove_chord_object (
- TL_SELECTIONS, chord);
-
- array_delete (self->chords,
- self->num_chords,
- chord);
-
- if (free)
- free_later (chord, chord_object_free);
-
- EVENTS_PUSH (ET_CHORD_OBJECT_REMOVED, self);
-}
-
-/**
* Removes a scale from the chord Track.
*/
void
@@ -200,5 +150,7 @@ chord_track_remove_scale (
void
chord_track_free (ChordTrack * self)
{
-
+ /* remove chords */
+ for (int i = 0; i < self->num_chord_regions; i++)
+ region_free (self->chord_regions[i]);
}
diff --git a/src/audio/instrument_track.c b/src/audio/instrument_track.c
index 279663c..cfda415 100644
--- a/src/audio/instrument_track.c
+++ b/src/audio/instrument_track.c
@@ -37,6 +37,7 @@
#include "gui/widgets/track.h"
#include "gui/widgets/automation_track.h"
#include "utils/arrays.h"
+#include "utils/stoat.h"
#include <gtk/gtk.h>
@@ -70,7 +71,7 @@ instrument_track_setup (InstrumentTrack * self)
* @param midi_events MidiEvents to fill (from
* Piano Roll Port for example).
*/
-__attribute__((annotate("realtime")))
+REALTIME
void
instrument_track_fill_midi_events (
InstrumentTrack * track,
diff --git a/src/audio/marker_track.c b/src/audio/marker_track.c
index fe2b3b0..8839b72 100644
--- a/src/audio/marker_track.c
+++ b/src/audio/marker_track.c
@@ -55,8 +55,7 @@ marker_track_default ()
void
marker_track_add_marker (
MarkerTrack * track,
- Marker * marker,
- int gen_widget)
+ Marker * marker)
{
g_warn_if_fail (
track->type == TRACK_TYPE_MARKER && marker);
@@ -70,13 +69,13 @@ marker_track_add_marker (
marker->obj_info.lane_trans);
marker_set_track (marker, track);
+ array_double_size_if_full (
+ track->markers, track->num_markers,
+ track->markers_size, Marker *);
array_append (track->markers,
track->num_markers,
marker);
- if (gen_widget)
- marker_gen_widget (marker);
-
EVENTS_PUSH (ET_MARKER_CREATED, marker);
}
diff --git a/src/audio/meson.build b/src/audio/meson.build
index ff74282..07b8e36 100644
--- a/src/audio/meson.build
+++ b/src/audio/meson.build
@@ -1,9 +1,27 @@
+# Copyright (C) 2019 Alexandros Theodotou <alex at zrythm dot org>
+#
+# This file is part of Zrythm
+#
+# Zrythm is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Affero General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# Zrythm 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 Affero General Public License for more details.
+#
+# You should have received a copy of the GNU Affero General Public License
+# along with Zrythm. If not, see <https://www.gnu.org/licenses/>.
+
audio_srcs = [
'audio_region.c',
'audio_track.c',
'automatable.c',
'automation_curve.c',
'automation_point.c',
+ 'automation_region.c',
'automation_track.c',
'automation_tracklist.c',
'bus_track.c',
@@ -11,6 +29,7 @@ audio_srcs = [
'channel_track.c',
'chord_descriptor.c',
'chord_object.c',
+ 'chord_region.c',
'chord_track.c',
'control_room.c',
'engine.c',
diff --git a/src/audio/midi_note.c b/src/audio/midi_note.c
index 9863c6a..e42a323 100644
--- a/src/audio/midi_note.c
+++ b/src/audio/midi_note.c
@@ -301,8 +301,9 @@ midi_note_delete (MidiNote * midi_note)
* timeline).
*/
int
-midi_note_hit (MidiNote * midi_note,
- Position * pos)
+midi_note_hit (
+ MidiNote * midi_note,
+ Position * pos)
{
Position local_pos;
Region * region = midi_note->region;
@@ -346,5 +347,8 @@ midi_note_free (MidiNote * self)
velocity_free_all (self->vel);
+ if (self->region_name)
+ g_free (self->region_name);
+
free (self);
}
diff --git a/src/audio/midi_region.c b/src/audio/midi_region.c
index ac148c9..901a2af 100644
--- a/src/audio/midi_region.c
+++ b/src/audio/midi_region.c
@@ -40,16 +40,15 @@ midi_region_new (
const Position * end_pos,
int is_main)
{
- MidiRegion * midi_region =
+ MidiRegion * self =
calloc (1, sizeof (MidiRegion));
- region_init ((Region *) midi_region,
- REGION_TYPE_MIDI,
- start_pos,
- end_pos,
- is_main);
+ self->type = REGION_TYPE_MIDI;
- return midi_region;
+ region_init (
+ self, start_pos, end_pos, is_main);
+
+ return self;
}
/**
@@ -75,14 +74,11 @@ midi_region_print_midi_notes (
/**
* Adds the MidiNote to the given Region.
- *
- * @param gen_widget Generate a MidiNoteWidget.
*/
void
midi_region_add_midi_note (
MidiRegion * region,
- MidiNote * midi_note,
- int gen_widget)
+ MidiNote * midi_note)
{
g_warn_if_fail (
midi_note->obj_info.counterpart ==
@@ -99,9 +95,6 @@ midi_region_add_midi_note (
region->num_midi_notes,
midi_note);
- if (gen_widget)
- midi_note_gen_widget (midi_note);
-
EVENTS_PUSH (ET_MIDI_NOTE_CREATED,
midi_note);
}
diff --git a/src/audio/region.c b/src/audio/region.c
index 6afc406..f033dbb 100644
--- a/src/audio/region.c
+++ b/src/audio/region.c
@@ -18,6 +18,8 @@
*/
#include "audio/audio_region.h"
+#include "audio/automation_region.h"
+#include "audio/chord_region.h"
#include "audio/channel.h"
#include "audio/midi_note.h"
#include "audio/midi_region.h"
@@ -26,8 +28,10 @@
#include "audio/track.h"
#include "ext/audio_decoder/ad.h"
#include "gui/widgets/audio_region.h"
+#include "gui/widgets/automation_region.h"
#include "gui/widgets/bot_dock_edge.h"
#include "gui/widgets/center_dock.h"
+#include "gui/widgets/chord_region.h"
#include "gui/widgets/clip_editor.h"
#include "gui/widgets/main_window.h"
#include "gui/widgets/midi_arranger.h"
@@ -63,12 +67,10 @@ ARRANGER_OBJ_DEFINE_MOVABLE_W_LENGTH (
void
region_init (
Region * self,
- const RegionType type,
const Position * start_pos,
const Position * end_pos,
const int is_main)
{
- g_message ("creating region");
position_set_to_pos (&self->start_pos,
start_pos);
position_set_to_pos (&self->end_pos,
@@ -82,20 +84,11 @@ region_init (
position_set_to_pos (&self->loop_end_pos,
&self->true_end_pos);
self->linked_region_name = NULL;
- self->type = type;
if (is_main)
{
- if (type == REGION_TYPE_MIDI)
- {
- ARRANGER_OBJECT_SET_AS_MAIN (
- REGION, Region, region);
- }
- else if (type == REGION_TYPE_AUDIO)
- {
- /* TODO */
-
- }
+ ARRANGER_OBJECT_SET_AS_MAIN (
+ REGION, Region, region);
}
}
@@ -137,31 +130,53 @@ region_init_loaded (Region * self)
region_find_by_name (
self->linked_region_name);
- if (self->type == REGION_TYPE_AUDIO)
- {
- /* reload audio */
- struct adinfo nfo;
- SRC_DATA src_data;
- long out_buff_size;
-
- audio_decode (
- &nfo, &src_data,
- &self->buff, &out_buff_size,
- self->filename);
-
- self->buff_size =
- src_data.output_frames_gen;
- self->channels = nfo.channels;
- }
- else if (self->type == REGION_TYPE_MIDI)
+ int i;
+ switch (self->type)
{
- MidiNote * mn;
- for (int i = 0; i < self->num_midi_notes; i++)
- {
- mn = self->midi_notes[i];
- mn->region = self;
- midi_note_init_loaded (mn);
+ case REGION_TYPE_AUDIO:
+ {
+ /* reload audio */
+ struct adinfo nfo;
+ SRC_DATA src_data;
+ long out_buff_size;
+
+ audio_decode (
+ &nfo, &src_data,
+ &self->buff, &out_buff_size,
+ self->filename);
+
+ self->buff_size =
+ src_data.output_frames_gen;
+ self->channels = nfo.channels;
+ }
+ break;
+ case REGION_TYPE_MIDI:
+ {
+ MidiNote * mn;
+ for (i = 0; i < self->num_midi_notes; i++)
+ {
+ mn = self->midi_notes[i];
+ mn->region = self;
+ midi_note_init_loaded (mn);
+ }
+ }
+ break;
+ case REGION_TYPE_CHORD:
+ {
+ ChordObject * chord;
+ for (i = 0; i < self->num_chord_objects;
+ i++)
+ {
+ chord = self->chord_objects[i];
+ chord_object_init_loaded (chord);
+ }
}
+ break;
+ case REGION_TYPE_AUTOMATION:
+ {
+ /* TODO */
+ }
+ break;
}
ARRANGER_OBJECT_SET_AS_MAIN (
@@ -271,19 +286,22 @@ region_gen_widget (
else if (i == 3)
r = region_get_lane_trans_region (r);
+#define GEN_W(type,sc) \
+ case REGION_TYPE_##type: \
+ r->widget = \
+ Z_REGION_WIDGET ( \
+ sc##_region_widget_new (r)); \
+ break
+
switch (r->type)
{
- case REGION_TYPE_MIDI:
- r->widget =
- Z_REGION_WIDGET (
- midi_region_widget_new (r));
- break;
- case REGION_TYPE_AUDIO:
- r->widget =
- Z_REGION_WIDGET (
- audio_region_widget_new (r));
- break;
+ GEN_W (MIDI, midi);
+ GEN_W (AUDIO, audio);
+ GEN_W (AUTOMATION, automation);
+ GEN_W (CHORD, chord);
}
+
+#undef GEN_W
}
}
@@ -638,46 +656,118 @@ region_clone (
Region * region,
RegionCloneFlag flag)
{
- int is_main = 0;
+ int is_main = 0, i, j;
if (flag == REGION_CLONE_COPY_MAIN)
is_main = 1;
Region * new_region = NULL;
- if (region->type == REGION_TYPE_MIDI)
- {
- MidiRegion * mr =
- midi_region_new (
- &region->start_pos,
- &region->end_pos,
- is_main);
- MidiRegion * mr_orig = region;
- if (flag == REGION_CLONE_COPY ||
- flag == REGION_CLONE_COPY_MAIN)
- {
- for (int i = 0;
- i < mr_orig->num_midi_notes; i++)
- {
- MidiNote * mn =
- midi_note_clone (
- mr_orig->midi_notes[i],
- MIDI_NOTE_CLONE_COPY_MAIN);
-
- midi_region_add_midi_note (
- mr, mn, F_NO_GEN_WIDGET);
- }
- }
-
- new_region = (Region *) mr;
- }
- else if (region->type == REGION_TYPE_AUDIO)
+ switch (region->type)
{
- Region * ar =
- audio_region_new (
- region->filename,
- &region->start_pos,
- is_main);
-
- new_region = ar;
+ case REGION_TYPE_MIDI:
+ {
+ MidiRegion * mr =
+ midi_region_new (
+ &region->start_pos,
+ &region->end_pos,
+ is_main);
+ MidiRegion * mr_orig = region;
+ if (flag == REGION_CLONE_COPY ||
+ flag == REGION_CLONE_COPY_MAIN)
+ {
+ for (i = 0;
+ i < mr_orig->num_midi_notes; i++)
+ {
+ MidiNote * mn =
+ midi_note_clone (
+ mr_orig->midi_notes[i],
+ MIDI_NOTE_CLONE_COPY_MAIN);
+
+ midi_region_add_midi_note (
+ mr, mn);
+ }
+ }
+
+ new_region = (Region *) mr;
+ }
+ break;
+ case REGION_TYPE_AUDIO:
+ {
+ Region * ar =
+ audio_region_new (
+ region->filename,
+ &region->start_pos,
+ is_main);
+
+ new_region = ar;
+ }
+ break;
+ case REGION_TYPE_AUTOMATION:
+ {
+ Region * ar =
+ automation_region_new (
+ &region->start_pos,
+ &region->end_pos,
+ is_main);
+ Region * ar_orig = region;
+
+ AutomationPoint * src_ap, * dest_ap;
+ AutomationCurve * src_ac, * dest_ac;
+
+ /* add automation points */
+ for (j = 0; j < ar_orig->num_aps; j++)
+ {
+ src_ap = ar_orig->aps[j];
+ dest_ap =
+ automation_point_new_float (
+ src_ap->fvalue,
+ &src_ap->pos, F_MAIN);
+ automation_region_add_ap (
+ ar, dest_ap, 0);
+ }
+
+ /* add automation curves */
+ for (j = 0; j < ar_orig->num_acs; j++)
+ {
+ src_ac = ar_orig->acs[j];
+ dest_ac =
+ automation_curve_new (
+ ar, &src_ac->pos);
+ automation_region_add_ac (
+ ar, dest_ac);
+ }
+
+ new_region = ar;
+ }
+ break;
+ case REGION_TYPE_CHORD:
+ {
+ Region * cr =
+ chord_region_new (
+ &region->start_pos,
+ &region->end_pos,
+ is_main);
+ Region * cr_orig = region;
+ if (flag == REGION_CLONE_COPY ||
+ flag == REGION_CLONE_COPY_MAIN)
+ {
+ ChordObject * co;
+ for (i = 0;
+ i < cr_orig->num_chord_objects;
+ i++)
+ {
+ co =
+ chord_object_clone (
+ cr_orig->chord_objects[i],
+ CHORD_OBJECT_CLONE_COPY_MAIN);
+
+ chord_region_add_chord_object (
+ cr, co);
+ }
+ }
+
+ new_region = cr;
+ }
+ break;
}
/* set caches */
@@ -733,10 +823,10 @@ region_clone (
*/
void
region_timeline_pos_to_local (
- Region * region,
- Position * timeline_pos,
- Position * local_pos,
- int normalize)
+ Region * region,
+ const Position * timeline_pos,
+ Position * local_pos,
+ int normalize)
{
long diff_ticks;
@@ -879,10 +969,21 @@ region_free (Region * self)
self->widget = NULL;
region_widget_delete (widget);
}
- if (self->type == REGION_TYPE_MIDI)
- midi_region_free_members (self);
- if (self->type == REGION_TYPE_AUDIO)
- audio_region_free_members (self);
+
+#define FREE_R(type,sc) \
+ case REGION_TYPE_##type: \
+ sc##_region_free_members (self); \
+ break
+
+ switch (self->type)
+ {
+ FREE_R (MIDI, midi);
+ FREE_R (AUDIO, audio);
+ FREE_R (CHORD, chord);
+ FREE_R (AUTOMATION, automation);
+ }
+
+#undef FREE_R
free (self);
}
diff --git a/src/audio/routing.c b/src/audio/routing.c
index 4c2d868..e5c2cb7 100644
--- a/src/audio/routing.c
+++ b/src/audio/routing.c
@@ -39,6 +39,7 @@
#include "audio/track.h"
#include "project.h"
#include "utils/arrays.h"
+#include "utils/stoat.h"
#ifdef HAVE_JACK
#include <jack/thread.h>
@@ -535,7 +536,7 @@ graph_worker_thread (void * g)
return 0;
}
-__attribute__((annotate("realtime")))
+REALTIME
static void *
graph_main_thread (void * arg)
{
diff --git a/src/audio/snap_grid.c b/src/audio/snap_grid.c
index 7464278..6970cae 100644
--- a/src/audio/snap_grid.c
+++ b/src/audio/snap_grid.c
@@ -23,6 +23,7 @@
#include "audio/snap_grid.h"
#include "audio/transport.h"
#include "project.h"
+#include "utils/algorithms.h"
#include <gtk/gtk.h>
@@ -267,82 +268,91 @@ snap_grid_stringize (NoteLength note_length,
}
/**
- * Returns the next or previous SnapGrid Point
+ * Returns the next or previous SnapGrid Point.
*
- * @param SnapGrid* snap grid to search in
- * @param Position* position to search for
- * @Param int return next or prev position
+ * @param self Snap grid to search in.
+ * @param pos Position to search for.
+ * @param return_prev 1 to return the previous
+ * element or 0 to return the next.
*/
Position *
-snap_grid_get_nearby_snap_point(SnapGrid *self, Position *pos, int before)
+snap_grid_get_nearby_snap_point (
+ SnapGrid * self,
+ Position * pos,
+ int return_prev)
{
+ Position * ret_pos = NULL;
+ algorithms_binary_search_nearby (
+ self->snap_points, pos, return_prev,
+ self->num_snap_points, Position *,
+ position_compare, &, ret_pos, NULL);
+
+ return ret_pos;
+
// init values
- int first = 0;
- int last = self->num_snap_points;
- int middle = (first + last) / 2;
- int pivot_is_before_pos, pivot_succ_is_before_pos;
- Position *pivot, *pivot_succ;
+ /*int first = 0;*/
+ /*int last = self->num_snap_points;*/
+ /*int middle = (first + last) / 2;*/
+ /*int pivot_is_before_pos, pivot_succ_is_before_pos;*/
+ /*Position *pivot, *pivot_succ;*/
- // return if SnapGrid has no entries
- if (first == last)
- {
- return NULL;
- }
+ /*// return if SnapGrid has no entries*/
+ /*if (first == last)*/
+ /*{*/
+ /*return NULL;*/
+ /*}*/
- // search loops, exit if pos is not in array
- while (first <= last)
- {
- pivot = &self->snap_points[middle];
- pivot_succ = NULL;
- pivot_succ_is_before_pos = 0;
+ /*// search loops, exit if pos is not in array*/
+ /*while (first <= last)*/
+ /*{*/
+ /*pivot = &self->snap_points[middle];*/
+ /*pivot_succ = NULL;*/
+ /*pivot_succ_is_before_pos = 0;*/
- if (middle == 0 && before) {
- return &self->snap_points[0];
- }
+ /*if (middle == 0 && return_prev) {*/
+ /*return &self->snap_points[0];*/
+ /*}*/
- // Return next/previous item if pivot is the searched position
- if (position_compare(pivot, pos) == 0) {
- if (before ) {
- return &self->snap_points[middle - 1];
- }
- else
- {
- return &self->snap_points[middle + 1];
- }
- }
+ /*// Return next/previous item if pivot is the searched position*/
+ /*if (position_compare(pivot, pos) == 0) {*/
+ /*if (return_prev)*/
+ /*return &self->snap_points[middle - 1];*/
+ /*else*/
+ /*return &self->snap_points[middle + 1];*/
+ /*}*/
- // Select pivot successor if possible
- if (middle < last)
- {
- pivot_succ = &self->snap_points[middle + 1];
- pivot_succ_is_before_pos =
- position_compare(
- pivot_succ, pos) <= 0;
- }
- pivot_is_before_pos =
- position_compare(
- pivot, pos) <= 0;
+ /*// Select pivot successor if possible*/
+ /*if (middle < last)*/
+ /*{*/
+ /*pivot_succ = &self->snap_points[middle + 1];*/
+ /*pivot_succ_is_before_pos =*/
+ /*position_compare(*/
+ /*pivot_succ, pos) <= 0;*/
+ /*}*/
+ /*pivot_is_before_pos =*/
+ /*position_compare(*/
+ /*pivot, pos) <= 0;*/
- // if pivot and pivot_succ are before pos, search in the second half on next iteration
- if (pivot_is_before_pos && pivot_succ_is_before_pos)
- {
- first = middle + 1;
- }
- else if (pivot_is_before_pos) // pos is between pivot and pivot_succ
- {
- if (before) {
- return pivot;
- } else {
- return pivot_succ;
- }
- }
- else { // if pivot_succ and pivot are behind pos, search in the first half on next iteration
- last = middle;
- }
+ /*// if pivot and pivot_succ are before pos, search in the second half on next iteration*/
+ /*if (pivot_is_before_pos && pivot_succ_is_before_pos)*/
+ /*{*/
+ /*first = middle + 1;*/
+ /*}*/
+ /*else if (pivot_is_before_pos) // pos is between pivot and pivot_succ*/
+ /*{*/
+ /*if (return_prev) {*/
+ /*return pivot;*/
+ /*} else {*/
+ /*return pivot_succ;*/
+ /*}*/
+ /*}*/
+ /*else { // if pivot_succ and pivot are behind pos, search in the first half on next iteration*/
+ /*last = middle;*/
+ /*}*/
- // recalculate middle position
- middle = (first + last) / 2;
- }
+ /*// recalculate middle position*/
+ /*middle = (first + last) / 2;*/
+ /*}*/
- return NULL;
-} \ No newline at end of file
+ /*return NULL;*/
+}
diff --git a/src/audio/track.c b/src/audio/track.c
index fc4bbf7..40969bd 100644
--- a/src/audio/track.c
+++ b/src/audio/track.c
@@ -59,12 +59,6 @@ track_init_loaded (Track * track)
lane->track = track;
track_lane_init_loaded (lane);
}
- ChordObject * chord;
- for (i = 0; i < track->num_chords; i++)
- {
- chord = track->chords[i];
- chord_object_init_loaded (chord);
- }
ScaleObject * scale;
for (i = 0; i < track->num_scales; i++)
{
@@ -99,21 +93,24 @@ track_init_loaded (Track * track)
*/
static void
track_add_lane (
- Track * track)
+ Track * self)
{
- track->lanes[track->num_lanes++] =
- track_lane_new (track, track->num_lanes);
+ array_double_size_if_full (
+ self->lanes, self->num_lanes,
+ self->lanes_size, TrackLane *);
+ self->lanes[self->num_lanes++] =
+ track_lane_new (self, self->num_lanes);
EVENTS_PUSH (ET_TRACK_LANE_ADDED,
- track->lanes[track->num_lanes - 1]);
+ self->lanes[self->num_lanes - 1]);
}
void
-track_init (Track * track)
+track_init (Track * self)
{
- track->visible = 1;
- track->handle_pos = 1;
- track_add_lane (track);
+ self->visible = 1;
+ self->handle_pos = 1;
+ track_add_lane (self);
}
/**
@@ -452,9 +449,9 @@ track_get_last_region (
for (j = 0; j < lane->num_regions; j++)
{
r = lane->regions[j];
- if (position_compare (
+ if (position_is_after (
&r->end_pos,
- &tmp) > 0)
+ &tmp))
{
last_region = r;
position_set_to_pos (
@@ -464,48 +461,23 @@ track_get_last_region (
}
}
- return last_region;
-}
-
-/**
- * Returns the last region in the track, or NULL.
- */
-AutomationPoint *
-track_get_last_automation_point (
- Track * track)
-{
AutomationTracklist * atl =
- track_get_automation_tracklist (track);
- if (!atl)
- return NULL;
-
- int i, j;
- AutomationPoint * last_ap = NULL, * ap;
+ &track->automation_tracklist;
AutomationTrack * at;
- Position tmp;
- position_init (&tmp);
-
for (i = 0; i < atl->num_ats; i++)
{
at = atl->ats[i];
-
- for (j = 0; j < at->num_aps;
- j++)
+ r = automation_track_get_last_region (at);
+ if (position_is_after (
+ &r->end_pos, &tmp))
{
- ap = at->aps[j];
-
- if (position_compare (
- &ap->pos,
- &tmp) > 0)
- {
- last_ap = ap;
- position_set_to_pos (
- &tmp, &ap->pos);
- }
+ last_region = r;
+ position_set_to_pos (
+ &tmp, &r->end_pos);
}
}
- return last_ap;
+ return last_region;
}
/**
@@ -541,21 +513,21 @@ track_setup (Track * track)
* The Region must be the main region (see
* ArrangerObjectInfo).
*
+ * @param at The AutomationTrack of this Region, if
+ * automation region.
* @param lane_pos The position of the lane to add
- * to.
+ * to, if applicable.
* @param gen_name Generate a unique region name or
* not. This will be 0 if the caller already
* generated a unique name.
- * @param gen_widget Generate a RegionWidget for
- * the Region.
*/
void
track_add_region (
Track * track,
Region * region,
+ AutomationTrack * at,
int lane_pos,
- int gen_name,
- int gen_widget)
+ int gen_name)
{
g_warn_if_fail (
(track->type == TRACK_TYPE_INSTRUMENT ||
@@ -589,19 +561,52 @@ track_add_region (
g_free (name);
}
- track_lane_add_region (
- track->lanes[lane_pos],
- region);
+ int add_lane = 0, add_at = 0, add_chord = 0;
+ switch (region->type)
+ {
+ case REGION_TYPE_MIDI:
+ add_lane = 1;
+ break;
+ case REGION_TYPE_AUDIO:
+ add_lane = 1;
+ break;
+ case REGION_TYPE_AUTOMATION:
+ add_at = 1;
+ break;
+ case REGION_TYPE_CHORD:
+ add_chord = 1;
+ break;
+ }
+
+ if (add_lane)
+ {
+ track_lane_add_region (
+ track->lanes[lane_pos],
+ region);
+
+ /* enable extra lane if necessary */
+ if (lane_pos == track->num_lanes - 1)
+ {
+ track_add_lane (track);
+ }
+ }
- if (gen_widget)
+ if (add_at)
{
- region_gen_widget (region);
+ automation_track_add_region (
+ at, region);
}
- /* enable extra lane if necessary */
- if (lane_pos == track->num_lanes - 1)
+ if (add_chord)
{
- track_add_lane (track);
+ g_warn_if_fail (track == P_CHORD_TRACK);
+ array_double_size_if_full (
+ track->chord_regions,
+ track->num_chord_regions,
+ track->chord_regions_size, Region *);
+ array_append (track->chord_regions,
+ track->num_chord_regions,
+ region);
}
EVENTS_PUSH (ET_REGION_CREATED,
@@ -673,6 +678,9 @@ track_add_modulator (
Track * track,
Modulator * modulator)
{
+ array_double_size_if_full (
+ track->modulators, track->num_modulators,
+ track->modulators_size, Modulator *);
array_append (track->modulators,
track->num_modulators,
modulator);
@@ -695,11 +703,6 @@ track_free (Track * track)
for (i = 0; i < track->num_lanes; i++)
track_lane_free (track->lanes[i]);
- /* remove chords */
- /* FIXME move inside *_track_free */
- for (i = 0; i < track->num_chords; i++)
- chord_object_free (track->chords[i]);
-
/* remove automation points, curves, tracks,
* lanes*/
/* FIXME move inside *_track_free */
@@ -819,8 +822,8 @@ track_get_channel (Track * track)
*/
Region *
track_get_region_at_pos (
- Track * track,
- Position * pos)
+ const Track * track,
+ const Position * pos)
{
int i, j;
@@ -835,17 +838,29 @@ track_get_region_at_pos (
for (j = 0; j < lane->num_regions; j++)
{
- r = lane->regions[i];
- if (position_compare (
- pos,
- &r->start_pos) >= 0 &&
- position_compare (
- pos,
- &r->end_pos) <= 0)
+ r = lane->regions[j];
+ if (position_is_after_or_equal (
+ pos, &r->start_pos) &&
+ position_is_before_or_equal (
+ pos, &r->end_pos))
return r;
}
}
}
+ else if (track->type == TRACK_TYPE_CHORD)
+ {
+ Region * r;
+
+ for (j = 0; j < track->num_chord_regions; j++)
+ {
+ r = track->chord_regions[j];
+ if (position_is_after_or_equal (
+ pos, &r->start_pos) &&
+ position_is_before_or_equal (
+ pos, &r->end_pos))
+ return r;
+ }
+ }
return NULL;
}
diff --git a/src/audio/track_lane.c b/src/audio/track_lane.c
index 6cdea86..ff3ea60 100644
--- a/src/audio/track_lane.c
+++ b/src/audio/track_lane.c
@@ -62,6 +62,11 @@ track_lane_new (
self->track = track;
self->track_pos = track->pos;
+ self->regions_size = 1;
+ self->regions =
+ malloc (self->regions_size *
+ sizeof (Region *));
+
return self;
}
@@ -73,8 +78,15 @@ track_lane_add_region (
TrackLane * self,
Region * region)
{
+ g_return_if_fail (
+ region->type == REGION_TYPE_AUDIO ||
+ region->type == REGION_TYPE_MIDI);
+
region_set_lane (region, self);
+ array_double_size_if_full (
+ self->regions, self->num_regions,
+ self->regions_size, Region *);
array_append (self->regions,
self->num_regions,
region);
diff --git a/src/gui/backend/automation_editor.c b/src/gui/backend/automation_editor.c
new file mode 100644
index 0000000..233cfb8
--- /dev/null
+++ b/src/gui/backend/automation_editor.c
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2019 Alexandros Theodotou <alex at zrythm dot org>
+ *
+ * This file is part of Zrythm
+ *
+ * Zrythm is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Zrythm 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 Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with Zrythm. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+/**
+ * \file
+ *
+ * Automation clip editor backend.
+ *
+ * This is meant to be serialized along with each
+ * project.
+ */
+
+#include <stdlib.h>
+
+#include "gui/backend/automation_editor.h"
+/*#include "gui/widgets/chord_editor.h"*/
+#include "project.h"
+
+void
+automation_editor_init (
+ AutomationEditor * self)
+{
+ /* TODO */
+}
+
+
diff --git a/src/gui/backend/automation_selections.c b/src/gui/backend/automation_selections.c
new file mode 100644
index 0000000..d93a549
--- /dev/null
+++ b/src/gui/backend/automation_selections.c
@@ -0,0 +1,545 @@
+/*
+ * Copyright (C) 2019 Alexandros Theodotou <alex at zrythm dot org>
+ *
+ * This file is part of Zrythm
+ *
+ * Zrythm is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Zrythm 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 Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+#include "audio/chord_track.h"
+#include "audio/engine.h"
+#include "audio/position.h"
+#include "audio/track.h"
+#include "audio/transport.h"
+#include "gui/backend/events.h"
+#include "gui/backend/automation_selections.h"
+#include "gui/widgets/audio_region.h"
+#include "gui/widgets/midi_region.h"
+#include "project.h"
+#include "utils/arrays.h"
+#include "utils/audio.h"
+#include "utils/flags.h"
+#include "utils/objects.h"
+#include "utils/yaml.h"
+
+#include <gtk/gtk.h>
+
+#define ADD_OBJECT(caps,sc) \
+ if (!array_contains ( \
+ ts->sc##s, ts->num_##sc##s, sc)) \
+ { \
+ array_append ( \
+ ts->sc##s, ts->num_##sc##s, sc); \
+ EVENTS_PUSH ( \
+ ET_ARRANGER_OBJECT_SELECTION_CHANGED, \
+ &sc->obj_info); \
+ }
+
+#define REMOVE_OBJECT(caps,sc) \
+ if (!array_contains ( \
+ ts->sc##s, ts->num_##sc##s, sc)) \
+ { \
+ EVENTS_PUSH ( \
+ ET_ARRANGER_OBJECT_SELECTION_CHANGED, \
+ &sc->obj_info); \
+ return; \
+ } \
+ array_delete ( \
+ ts->sc##s, ts->num_##sc##s, sc)
+
+
+void
+automation_selections_init_loaded (
+ AutomationSelections * ts)
+{
+ int i;
+
+#define _SET_OBJ(sc) \
+ for (i = 0; i < ts->num_##sc##s; i++) \
+ ts->sc##s[i] = sc##_find (ts->sc##s[i]);
+
+ _SET_OBJ (automation_point);
+
+#undef _SET_OBJ
+}
+
+/**
+ * Returns if there are any selections.
+ */
+int
+automation_selections_has_any (
+ AutomationSelections * ts)
+{
+ return (
+ ts->num_automation_points > 0);
+}
+
+/**
+ * Sets the cache Position's for each object in
+ * the selection.
+ *
+ * Used by the ArrangerWidget's.
+ */
+void
+automation_selections_set_cache_poses (
+ AutomationSelections * ts)
+{
+ int i;
+
+#define SET_CACHE_POS_W_LENGTH(cc,sc) \
+ cc * sc; \
+ for (i = 0; i < ts->num_##sc##s; i++) \
+ { \
+ sc = ts->sc##s[i]; \
+ sc##_set_cache_start_pos ( \
+ sc, &sc->start_pos); \
+ sc##_set_cache_end_pos ( \
+ sc, &sc->end_pos); \
+ }
+
+#define SET_CACHE_POS(cc,sc) \
+ cc * sc; \
+ for (i = 0; i < ts->num_##sc##s; i++) \
+ { \
+ sc = ts->sc##s[i]; \
+ sc##_set_cache_pos ( \
+ sc, &sc->pos); \
+ }
+
+ SET_CACHE_POS (AutomationPoint, automation_point);
+
+#undef SET_CACHE_POS_W_LENGTH
+#undef SET_CACHE_POS
+}
+
+/**
+ * Set all transient Position's to their main
+ * counterparts.
+ */
+void
+automation_selections_reset_transient_poses (
+ AutomationSelections * ts)
+{
+ int i;
+
+#define RESET_TRANS_POS_W_LENGTH(caps,cc,sc) \
+ cc * sc; \
+ for (i = 0; i < ts->num_##sc##s; i++) \
+ { \
+ sc = ts->sc##s[i]; \
+ sc##_set_start_pos ( \
+ sc, &sc->start_pos, \
+ AO_UPDATE_ALL); \
+ sc##_set_end_pos ( \
+ sc, &sc->end_pos, \
+ AO_UPDATE_ALL); \
+ } \
+ EVENTS_PUSH (ET_##caps##_POSITIONS_CHANGED, \
+ NULL)
+
+#define RESET_TRANS_POS(caps,cc,sc) \
+ cc * sc; \
+ for (i = 0; i < ts->num_##sc##s; i++) \
+ { \
+ sc = ts->sc##s[i]; \
+ sc##_set_pos ( \
+ sc, &sc->pos, \
+ AO_UPDATE_ALL); \
+ } \
+ EVENTS_PUSH (ET_##caps##_POSITIONS_CHANGED, \
+ NULL)
+
+ RESET_TRANS_POS (
+ AUTOMATION_POINT, AutomationPoint,
+ automation_point);
+
+#undef RESET_TRANS_POS_W_LENGTH
+#undef RESET_TRANS_POS
+}
+
+/**
+ * Returns the position of the leftmost object.
+ *
+ * If transient is 1, the transient objects are
+ * checked instead.
+ *
+ * The return value will be stored in pos.
+ */
+void
+automation_selections_get_start_pos (
+ AutomationSelections * ts,
+ Position * pos,
+ int transient,
+ int global)
+{
+ position_set_to_bar (pos,
+ TRANSPORT->total_bars);
+ GtkWidget * widget = NULL;
+ (void) widget; // avoid unused warnings
+
+ int i;
+
+ ARRANGER_OBJ_SET_GIVEN_POS_TO (
+ ts, AutomationPoint, automation_point, pos,
+ transient, before, widget);
+}
+
+/**
+ * Returns the position of the rightmost object.
+ *
+ * If transient is 1, the transient objects are
+ * checked instead.
+ *
+ * The return value will be stored in pos.
+ */
+void
+automation_selections_get_end_pos (
+ AutomationSelections * ts,
+ Position * pos,
+ int transient,
+ int global)
+{
+ position_init (pos);
+ GtkWidget * widget = NULL;
+ (void) widget; // avoid unused warnings
+
+ int i;
+
+ ARRANGER_OBJ_SET_GIVEN_POS_TO (
+ ts, AutomationPoint, automation_point, pos,
+ transient, after, widget);
+}
+
+/**
+ * Gets first object's widget.
+ *
+ * If transient is 1, transient objects are checked
+ * instead.
+ */
+GtkWidget *
+automation_selections_get_first_object (
+ AutomationSelections * ts,
+ int transient)
+{
+ Position _pos;
+ Position * pos = &_pos;
+ GtkWidget * widget = NULL;
+ position_set_to_bar (
+ pos, TRANSPORT->total_bars);
+ int i;
+
+ ARRANGER_OBJ_SET_GIVEN_POS_TO (
+ ts, AutomationPoint, automation_point, pos,
+ transient, before, widget);
+
+ return widget;
+}
+
+/**
+ * Gets last object's widget.
+ *
+ * If transient is 1, transient objects rae checked
+ * instead.
+ */
+GtkWidget *
+automation_selections_get_last_object (
+ AutomationSelections * ts,
+ int transient)
+{
+ Position _pos;
+ Position * pos = &_pos;
+ GtkWidget * widget = NULL;
+ position_init (pos);
+ int i;
+
+ ARRANGER_OBJ_SET_GIVEN_POS_TO (
+ ts, AutomationPoint, automation_point, pos,
+ transient, after, widget);
+
+ return widget;
+}
+
+/**
+ * Adds an object to the selections.
+ */
+#define DEFINE_ADD_OBJECT(caps,cc,sc) \
+ void \
+ automation_selections_add_##sc ( \
+ AutomationSelections * ts, \
+ cc * sc) \
+ { \
+ ADD_OBJECT (caps, sc); \
+ }
+
+DEFINE_ADD_OBJECT (
+ AUTOMATION_POINT, AutomationPoint,
+ automation_point);
+
+#undef DEFINE_ADD_OBJECT
+
+#define DEFINE_REMOVE_OBJ(caps,cc,sc) \
+ void \
+ automation_selections_remove_##sc ( \
+ AutomationSelections * ts, \
+ cc * sc) \
+ { \
+ REMOVE_OBJECT (caps, sc); \
+ }
+
+DEFINE_REMOVE_OBJ (
+ AUTOMATION_POINT, AutomationPoint,
+ automation_point);
+
+#undef DEFINE_REMOVE_OBJ
+
+#define DEFINE_CONTAINS_OBJ(caps,cc,sc) \
+ int \
+ automation_selections_contains_##sc ( \
+ AutomationSelections * self, \
+ cc * sc) \
+ { \
+ return \
+ array_contains ( \
+ self->sc##s, self->num_##sc##s, sc); \
+ }
+
+DEFINE_CONTAINS_OBJ (
+ AUTOMATION_POINT, AutomationPoint,
+ automation_point);
+
+#undef DEFINE_CONTAINS_OBJ
+
+/**
+ * Set all main Position's to their transient
+ * counterparts.
+ */
+void
+automation_selections_set_to_transient_poses (
+ AutomationSelections * ts)
+{
+ int i;
+
+#define SET_TO_TRANS_POS(caps,cc,sc) \
+ cc * sc, * sc##_trans; \
+ for (i = 0; i < ts->num_##sc##s; i++) \
+ { \
+ sc = ts->sc##s[i]; \
+ sc##_trans = \
+ sc##_get_main_trans_##sc (sc); \
+ sc##_set_pos ( \
+ sc, &sc##_trans->pos, \
+ AO_UPDATE_ALL); \
+ } \
+ EVENTS_PUSH (ET_##caps##_POSITIONS_CHANGED, \
+ NULL)
+
+ SET_TO_TRANS_POS (
+ AUTOMATION_POINT, AutomationPoint,
+ automation_point);
+
+#undef SET_TO_TRANS_POS
+}
+
+/**
+ * Clears selections.
+ */
+void
+automation_selections_clear (
+ AutomationSelections * ts)
+{
+ int i;
+
+/* use caches because ts->* will be operated on. */
+#define AS_REMOVE_OBJS(caps,cc,sc) \
+ int num_##sc##s; \
+ cc * sc; \
+ static cc * sc##s[600]; \
+ for (i = 0; i < ts->num_##sc##s; i++) \
+ { \
+ sc##s[i] = ts->sc##s[i]; \
+ } \
+ num_##sc##s = ts->num_##sc##s; \
+ for (i = 0; i < num_##sc##s; i++) \
+ { \
+ sc = sc##s[i]; \
+ automation_selections_remove_##sc (ts, sc); \
+ EVENTS_PUSH ( \
+ ET_ARRANGER_OBJECT_SELECTION_CHANGED, \
+ &sc->obj_info); \
+ }
+
+ AS_REMOVE_OBJS (
+ AUTOMATION_POINT, AutomationPoint,
+ automation_point);
+
+#undef AS_REMOVE_OBJS
+}
+
+/**
+ * Clone the struct for copying, undoing, etc.
+ */
+AutomationSelections *
+automation_selections_clone (
+ AutomationSelections * src)
+{
+ AutomationSelections * new_ts =
+ calloc (1, sizeof (AutomationSelections));
+
+ int i;
+
+#define AS_CLONE_OBJS(caps,cc,sc) \
+ cc * sc, * new_##sc; \
+ for (i = 0; i < src->num_##sc##s; i++) \
+ { \
+ sc = src->sc##s[i]; \
+ new_##sc = \
+ sc##_clone (sc, caps##_CLONE_COPY_MAIN); \
+ array_append ( \
+ new_ts->sc##s, new_ts->num_##sc##s, \
+ new_##sc); \
+ }
+
+ AS_CLONE_OBJS (
+ AUTOMATION_POINT, AutomationPoint,
+ automation_point);
+
+#undef AS_CLONE_OBJS
+
+ return new_ts;
+}
+
+/**
+ * Similar to set_to_transient_poses, but handles
+ * values for objects that support them (like
+ * AutomationPoint's).
+ */
+void
+automation_selections_set_to_transient_values (
+ AutomationSelections * ts)
+{
+ AutomationPoint * ap;
+ for (int i = 0; i < ts->num_automation_points;
+ i++)
+ {
+ ap = ts->automation_points[i];
+ ap->fvalue =
+ automation_point_get_main_trans_automation_point (
+ ap)->fvalue;
+ }
+}
+
+
+/**
+ * Moves the AutomationSelections by the given
+ * amount of ticks.
+ *
+ * @param ticks Ticks to add.
+ * @param use_cached_pos Add the ticks to the cached
+ * Position's instead of the current Position's.
+ * @param ticks Ticks to add.
+ * @param update_flag ArrangerObjectUpdateFlag.
+ */
+void
+automation_selections_add_ticks (
+ AutomationSelections * ts,
+ long ticks,
+ int use_cached_pos,
+ ArrangerObjectUpdateFlag update_flag)
+{
+ int i;
+
+#define UPDATE_AS_POSES(cc,sc) \
+ cc * sc; \
+ for (i = 0; i < ts->num_##sc##s; i++) \
+ { \
+ sc = ts->sc##s[i]; \
+ sc##_move ( \
+ sc, ticks, use_cached_pos, \
+ update_flag); \
+ }
+
+ UPDATE_AS_POSES (
+ AutomationPoint, automation_point);
+
+#undef UPDATE_AS_POSES
+}
+
+void
+automation_selections_paste_to_pos (
+ AutomationSelections * ts,
+ Position * pos)
+{
+ int pos_ticks = position_to_ticks (pos);
+
+ /* get pos of earliest object */
+ Position start_pos;
+ automation_selections_get_start_pos (
+ ts, &start_pos, F_NO_TRANSIENTS, 0);
+ int start_pos_ticks =
+ position_to_ticks (&start_pos);
+
+ /* subtract the start pos from every object and
+ * add the given pos */
+#define DIFF (curr_ticks - start_pos_ticks)
+#define ADJUST_POSITION(x) \
+ curr_ticks = position_to_ticks (x); \
+ position_from_ticks (x, pos_ticks + DIFF)
+
+ int curr_ticks, i;
+ AutomationPoint * ap;
+ for (i = 0; i < ts->num_automation_points; i++)
+ {
+ ap =
+ ts->automation_points[i];
+
+ curr_ticks = position_to_ticks (&ap->pos);
+ position_from_ticks (&ap->pos,
+ pos_ticks + DIFF);
+ }
+#undef DIFF
+}
+
+/**
+ * Frees all the objects as well.
+ *
+ * To be used in actions where the selections are
+ * all clones.
+ */
+void
+automation_selections_free_full (
+ AutomationSelections * self)
+{
+ for (int i = 0;
+ i < self->num_automation_points; i++)
+ {
+ automation_point_free (
+ self->automation_points[i]);
+ }
+
+ automation_selections_free (self);
+}
+
+void
+automation_selections_free (
+ AutomationSelections * self)
+{
+ free (self);
+}
+
+SERIALIZE_SRC (
+ AutomationSelections, automation_selections)
+DESERIALIZE_SRC (
+ AutomationSelections, automation_selections)
+PRINT_YAML_SRC (
+ AutomationSelections, automation_selections)
diff --git a/src/gui/backend/chord_editor.c b/src/gui/backend/chord_editor.c
new file mode 100644
index 0000000..fd2613c
--- /dev/null
+++ b/src/gui/backend/chord_editor.c
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2019 Alexandros Theodotou <alex at zrythm dot org>
+ *
+ * This file is part of Zrythm
+ *
+ * Zrythm is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Zrythm 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 Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with Zrythm. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+/**
+ * \file
+ *
+ * Chord clip editor backend.
+ *
+ * This is meant to be serialized along with each
+ * project.
+ */
+
+#include <stdlib.h>
+
+#include "gui/backend/chord_editor.h"
+/*#include "gui/widgets/chord_editor.h"*/
+#include "project.h"
+
+void
+chord_editor_init (
+ ChordEditor * self)
+{
+ /* TODO */
+}
+
diff --git a/src/gui/backend/chord_selections.c b/src/gui/backend/chord_selections.c
new file mode 100644
index 0000000..aa0f423
--- /dev/null
+++ b/src/gui/backend/chord_selections.c
@@ -0,0 +1,517 @@
+/*
+ * Copyright (C) 2019 Alexandros Theodotou <alex at zrythm dot org>
+ *
+ * This file is part of Zrythm
+ *
+ * Zrythm is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Zrythm 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 Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+#include "audio/chord_track.h"
+#include "audio/engine.h"
+#include "audio/position.h"
+#include "audio/track.h"
+#include "audio/transport.h"
+#include "gui/backend/events.h"
+#include "gui/backend/chord_selections.h"
+#include "gui/widgets/audio_region.h"
+#include "gui/widgets/midi_region.h"
+#include "project.h"
+#include "utils/arrays.h"
+#include "utils/audio.h"
+#include "utils/flags.h"
+#include "utils/objects.h"
+#include "utils/yaml.h"
+
+#include <gtk/gtk.h>
+
+#define ADD_OBJECT(caps,sc) \
+ if (!array_contains ( \
+ ts->sc##s, ts->num_##sc##s, sc)) \
+ { \
+ array_append ( \
+ ts->sc##s, ts->num_##sc##s, sc); \
+ EVENTS_PUSH ( \
+ ET_ARRANGER_OBJECT_SELECTION_CHANGED, \
+ &sc->obj_info); \
+ }
+
+#define REMOVE_OBJECT(caps,sc) \
+ if (!array_contains ( \
+ ts->sc##s, ts->num_##sc##s, sc)) \
+ { \
+ EVENTS_PUSH ( \
+ ET_ARRANGER_OBJECT_SELECTION_CHANGED, \
+ &sc->obj_info); \
+ return; \
+ } \
+ array_delete ( \
+ ts->sc##s, ts->num_##sc##s, sc)
+
+
+void
+chord_selections_init_loaded (
+ ChordSelections * ts)
+{
+ int i;
+
+#define _SET_OBJ(sc) \
+ for (i = 0; i < ts->num_##sc##s; i++) \
+ ts->sc##s[i] = sc##_find (ts->sc##s[i]);
+
+ _SET_OBJ (chord_object);
+
+#undef _SET_OBJ
+}
+
+/**
+ * Returns if there are any selections.
+ */
+int
+chord_selections_has_any (
+ ChordSelections * ts)
+{
+ return (
+ ts->num_chord_objects > 0);
+}
+
+/**
+ * Sets the cache Position's for each object in
+ * the selection.
+ *
+ * Used by the ArrangerWidget's.
+ */
+void
+chord_selections_set_cache_poses (
+ ChordSelections * ts)
+{
+ int i;
+
+#define SET_CACHE_POS_W_LENGTH(cc,sc) \
+ cc * sc; \
+ for (i = 0; i < ts->num_##sc##s; i++) \
+ { \
+ sc = ts->sc##s[i]; \
+ sc##_set_cache_start_pos ( \
+ sc, &sc->start_pos); \
+ sc##_set_cache_end_pos ( \
+ sc, &sc->end_pos); \
+ }
+
+#define SET_CACHE_POS(cc,sc) \
+ cc * sc; \
+ for (i = 0; i < ts->num_##sc##s; i++) \
+ { \
+ sc = ts->sc##s[i]; \
+ sc##_set_cache_pos ( \
+ sc, &sc->pos); \
+ }
+
+ SET_CACHE_POS (ChordObject, chord_object);
+
+#undef SET_CACHE_POS_W_LENGTH
+#undef SET_CACHE_POS
+}
+
+/**
+ * Set all transient Position's to their main
+ * counterparts.
+ */
+void
+chord_selections_reset_transient_poses (
+ ChordSelections * ts)
+{
+ int i;
+
+#define RESET_TRANS_POS_W_LENGTH(caps,cc,sc) \
+ cc * sc; \
+ for (i = 0; i < ts->num_##sc##s; i++) \
+ { \
+ sc = ts->sc##s[i]; \
+ sc##_set_start_pos ( \
+ sc, &sc->start_pos, \
+ AO_UPDATE_ALL); \
+ sc##_set_end_pos ( \
+ sc, &sc->end_pos, \
+ AO_UPDATE_ALL); \
+ } \
+ EVENTS_PUSH (ET_##caps##_POSITIONS_CHANGED, \
+ NULL)
+
+#define RESET_TRANS_POS(caps,cc,sc) \
+ cc * sc; \
+ for (i = 0; i < ts->num_##sc##s; i++) \
+ { \
+ sc = ts->sc##s[i]; \
+ sc##_set_pos ( \
+ sc, &sc->pos, \
+ AO_UPDATE_ALL); \
+ } \
+ EVENTS_PUSH (ET_##caps##_POSITIONS_CHANGED, \
+ NULL)
+
+ RESET_TRANS_POS (
+ CHORD_OBJECT, ChordObject, chord_object);
+
+#undef RESET_TRANS_POS_W_LENGTH
+#undef RESET_TRANS_POS
+}
+
+/**
+ * Returns the position of the leftmost object.
+ *
+ * If transient is 1, the transient objects are
+ * checked instead.
+ *
+ * The return value will be stored in pos.
+ */
+void
+chord_selections_get_start_pos (
+ ChordSelections * ts,
+ Position * pos,
+ int transient,
+ int global)
+{
+ position_set_to_bar (pos,
+ TRANSPORT->total_bars);
+ GtkWidget * widget = NULL;
+ (void) widget; // avoid unused warnings
+
+ int i;
+
+ ARRANGER_OBJ_SET_GIVEN_POS_TO (
+ ts, ChordObject, chord_object, pos,
+ transient, before, widget);
+
+ if (global)
+ {
+ /* TODO convert to global pos */
+ }
+}
+
+/**
+ * Returns the position of the rightmost object.
+ *
+ * If transient is 1, the transient objects are
+ * checked instead.
+ *
+ * The return value will be stored in pos.
+ */
+void
+chord_selections_get_end_pos (
+ ChordSelections * ts,
+ Position * pos,
+ int transient,
+ int global)
+{
+ position_init (pos);
+ GtkWidget * widget = NULL;
+ (void) widget; // avoid unused warnings
+
+ int i;
+
+ ARRANGER_OBJ_SET_GIVEN_POS_TO (
+ ts, ChordObject, chord_object, pos,
+ transient, after, widget);
+
+ if (global)
+ {
+ /* TODO convert to global pos */
+ }
+}
+
+/**
+ * Gets first object's widget.
+ *
+ * If transient is 1, transient objects are checked
+ * instead.
+ */
+GtkWidget *
+chord_selections_get_first_object (
+ ChordSelections * ts,
+ int transient)
+{
+ Position _pos;
+ Position * pos = &_pos;
+ GtkWidget * widget = NULL;
+ position_set_to_bar (
+ pos, TRANSPORT->total_bars);
+ int i;
+
+ ARRANGER_OBJ_SET_GIVEN_POS_TO (
+ ts, ChordObject, chord_object, pos,
+ transient, before, widget);
+
+ return widget;
+}
+
+/**
+ * Gets last object's widget.
+ *
+ * If transient is 1, transient objects rae checked
+ * instead.
+ */
+GtkWidget *
+chord_selections_get_last_object (
+ ChordSelections * ts,
+ int transient)
+{
+ Position _pos;
+ Position * pos = &_pos;
+ GtkWidget * widget = NULL;
+ position_init (pos);
+ int i;
+
+ ARRANGER_OBJ_SET_GIVEN_POS_TO (
+ ts, ChordObject, chord_object, pos,
+ transient, after, widget);
+
+ return widget;
+}
+
+/**
+ * Adds an object to the selections.
+ */
+#define DEFINE_ADD_OBJECT(caps,cc,sc) \
+ void \
+ chord_selections_add_##sc ( \
+ ChordSelections * ts, \
+ cc * sc) \
+ { \
+ ADD_OBJECT (caps, sc); \
+ }
+
+DEFINE_ADD_OBJECT (
+ CHORD_OBJECT, ChordObject, chord_object);
+
+#undef DEFINE_ADD_OBJECT
+
+#define DEFINE_REMOVE_OBJ(caps,cc,sc) \
+ void \
+ chord_selections_remove_##sc ( \
+ ChordSelections * ts, \
+ cc * sc) \
+ { \
+ REMOVE_OBJECT (caps, sc); \
+ }
+
+DEFINE_REMOVE_OBJ (
+ CHORD_OBJECT, ChordObject, chord_object);
+
+#undef DEFINE_REMOVE_OBJ
+
+#define DEFINE_CONTAINS_OBJ(caps,cc,sc) \
+ int \
+ chord_selections_contains_##sc ( \
+ ChordSelections * self, \
+ cc * sc) \
+ { \
+ return \
+ array_contains ( \
+ self->sc##s, self->num_##sc##s, sc); \
+ }
+
+DEFINE_CONTAINS_OBJ (
+ CHORD_OBJECT, ChordObject, chord_object);
+
+#undef DEFINE_CONTAINS_OBJ
+
+/**
+ * Set all main Position's to their transient
+ * counterparts.
+ */
+void
+chord_selections_set_to_transient_poses (
+ ChordSelections * ts)
+{
+ int i;
+
+#define SET_TO_TRANS_POS(caps,cc,sc) \
+ cc * sc, * sc##_trans; \
+ for (i = 0; i < ts->num_##sc##s; i++) \
+ { \
+ sc = ts->sc##s[i]; \
+ sc##_trans = \
+ sc##_get_main_trans_##sc (sc); \
+ sc##_set_pos ( \
+ sc, &sc##_trans->pos, \
+ AO_UPDATE_ALL); \
+ } \
+ EVENTS_PUSH (ET_##caps##_POSITIONS_CHANGED, \
+ NULL)
+
+ SET_TO_TRANS_POS (
+ CHORD_OBJECT, ChordObject, chord_object);
+
+#undef SET_TO_TRANS_POS
+}
+
+/**
+ * Clears selections.
+ */
+void
+chord_selections_clear (
+ ChordSelections * ts)
+{
+ int i;
+
+/* use caches because ts->* will be operated on. */
+#define CS_REMOVE_OBJS(caps,cc,sc) \
+ int num_##sc##s; \
+ cc * sc; \
+ static cc * sc##s[600]; \
+ for (i = 0; i < ts->num_##sc##s; i++) \
+ { \
+ sc##s[i] = ts->sc##s[i]; \
+ } \
+ num_##sc##s = ts->num_##sc##s; \
+ for (i = 0; i < num_##sc##s; i++) \
+ { \
+ sc = sc##s[i]; \
+ chord_selections_remove_##sc (ts, sc); \
+ EVENTS_PUSH ( \
+ ET_ARRANGER_OBJECT_SELECTION_CHANGED, \
+ &sc->obj_info); \
+ }
+
+ CS_REMOVE_OBJS (
+ CHORD_OBJECT, ChordObject, chord_object);
+
+#undef CS_REMOVE_OBJS
+}
+
+/**
+ * Clone the struct for copying, undoing, etc.
+ */
+ChordSelections *
+chord_selections_clone (
+ ChordSelections * src)
+{
+ ChordSelections * new_ts =
+ calloc (1, sizeof (ChordSelections));
+
+ int i;
+
+#define CS_CLONE_OBJS(caps,cc,sc) \
+ cc * sc, * new_##sc; \
+ for (i = 0; i < src->num_##sc##s; i++) \
+ { \
+ sc = src->sc##s[i]; \
+ new_##sc = \
+ sc##_clone (sc, caps##_CLONE_COPY_MAIN); \
+ array_append ( \
+ new_ts->sc##s, new_ts->num_##sc##s, \
+ new_##sc); \
+ }
+
+ CS_CLONE_OBJS (
+ CHORD_OBJECT, ChordObject, chord_object);
+
+#undef CS_CLONE_OBJS
+
+ return new_ts;
+}
+
+/**
+ * Similar to set_to_transient_poses, but handles
+ * values for objects that support them (like
+ * AutomationPoint's).
+ */
+void
+chord_selections_set_to_transient_values (
+ ChordSelections * ts)
+{
+}
+
+/**
+ * Moves the ChordSelections by the given
+ * amount of ticks.
+ *
+ * @param ticks Ticks to add.
+ * @param use_cached_pos Add the ticks to the cached
+ * Position's instead of the current Position's.
+ * @param ticks Ticks to add.
+ * @param update_flag ArrangerObjectUpdateFlag.
+ */
+void
+chord_selections_add_ticks (
+ ChordSelections * ts,
+ long ticks,
+ int use_cached_pos,
+ ArrangerObjectUpdateFlag update_flag)
+{
+ int i;
+
+#define UPDATE_CS_POSES(cc,sc) \
+ cc * sc; \
+ for (i = 0; i < ts->num_##sc##s; i++) \
+ { \
+ sc = ts->sc##s[i]; \
+ sc##_move ( \
+ sc, ticks, use_cached_pos, \
+ update_flag); \
+ }
+
+ UPDATE_CS_POSES (
+ ChordObject, chord_object);
+
+#undef UPDATE_CS_POSES
+}
+
+void
+chord_selections_paste_to_pos (
+ ChordSelections * ts,
+ Position * pos)
+{
+ int pos_ticks = position_to_ticks (pos);
+
+ /* get pos of earliest object */
+ Position start_pos;
+ chord_selections_get_start_pos (
+ ts, &start_pos, F_NO_TRANSIENTS, 0);
+ int start_pos_ticks =
+ position_to_ticks (&start_pos);
+
+ /* subtract the start pos from every object and
+ * add the given pos */
+#define DIFF (curr_ticks - start_pos_ticks)
+#define ADJUST_POSITION(x) \
+ curr_ticks = position_to_ticks (x); \
+ position_from_ticks (x, pos_ticks + DIFF)
+
+ int curr_ticks, i;
+ ChordObject * chord;
+ for (i = 0; i < ts->num_chord_objects; i++)
+ {
+ chord = ts->chord_objects[i];
+
+ curr_ticks = position_to_ticks (&chord->pos);
+ position_from_ticks (&chord->pos,
+ pos_ticks + DIFF);
+ }
+#undef DIFF
+}
+
+void
+chord_selections_free (
+ ChordSelections * self)
+{
+ free (self);
+}
+
+SERIALIZE_SRC (
+ ChordSelections, chord_selections)
+DESERIALIZE_SRC (
+ ChordSelections, chord_selections)
+PRINT_YAML_SRC (
+ ChordSelections, chord_selections)
diff --git a/src/gui/backend/events.c b/src/gui/backend/events.c
index bc12460..6e2aafc 100644
--- a/src/gui/backend/events.c
+++ b/src/gui/backend/events.c
@@ -863,7 +863,7 @@ events_process (void * data)
case ET_TRACK_LANES_VISIBILITY_CHANGED:
tracklist_widget_soft_refresh (
MW_TRACKLIST);
- timeline_arranger_widget_refresh_visibility (
+ timeline_arranger_widget_update_visibility (
MW_TIMELINE);
break;
case ET_TRACK_ADDED:
@@ -1011,7 +1011,7 @@ events_process (void * data)
case ET_TRACK_LANE_ADDED:
tracklist_widget_soft_refresh (
MW_TRACKLIST);
- timeline_arranger_widget_refresh_visibility (
+ timeline_arranger_widget_update_visibility (
MW_TIMELINE);
break;
case ET_LOOP_TOGGLED:
diff --git a/src/gui/backend/meson.build b/src/gui/backend/meson.build
index 8ea1517..a0ed30d 100644
--- a/src/gui/backend/meson.build
+++ b/src/gui/backend/meson.build
@@ -1,6 +1,10 @@
backend_srcs = [
'arranger_object_info.c',
'audio_clip_editor.c',
+ 'automation_editor.c',
+ 'automation_selections.c',
+ 'chord_editor.c',
+ 'chord_selections.c',
'clip_editor.c',
'events.c',
'file_manager.c',
diff --git a/src/gui/backend/midi_arranger_selections.c b/src/gui/backend/midi_arranger_selections.c
index 6c4056f..0a9f746 100644
--- a/src/gui/backend/midi_arranger_selections.c
+++ b/src/gui/backend/midi_arranger_selections.c
@@ -108,7 +108,8 @@ void
midi_arranger_selections_get_end_pos (
MidiArrangerSelections * mas,
Position * pos,
- int transient)
+ int transient,
+ int global)
{
position_set_to_bar (pos,
TRANSPORT->total_bars);
@@ -121,6 +122,11 @@ midi_arranger_selections_get_end_pos (
ARRANGER_OBJ_SET_GIVEN_POS_TO (
mas, MidiNote, midi_note, start_pos,
transient, after, widget);
+
+ if (global)
+ {
+ /* TODO convert to global */
+ }
}
/**
@@ -501,7 +507,7 @@ midi_arranger_selections_paste_to_pos (
midi_note,
MIDI_NOTE_CLONE_COPY_MAIN);
midi_region_add_midi_note (
- cp->region, cp, F_GEN_WIDGET);
+ cp->region, cp);
}
#undef DIFF
}
diff --git a/src/gui/backend/timeline_selections.c b/src/gui/backend/timeline_selections.c
index fbceb06..277c093 100644
--- a/src/gui/backend/timeline_selections.c
+++ b/src/gui/backend/timeline_selections.c
@@ -71,9 +71,7 @@ timeline_selections_init_loaded (
_SET_OBJ (region);
_SET_OBJ (marker);
- _SET_OBJ (chord_object);
_SET_OBJ (scale_object);
- _SET_OBJ (automation_point);
#undef _SET_OBJ
}
@@ -87,10 +85,8 @@ timeline_selections_has_any (
{
return (
ts->num_regions > 0 ||
- ts->num_automation_points > 0 ||
ts->num_scale_objects > 0 ||
- ts->num_markers > 0 ||
- ts->num_chord_objects > 0);
+ ts->num_markers > 0);
}
/**
@@ -126,10 +122,8 @@ timeline_selections_set_cache_poses (
}
SET_CACHE_POS_W_LENGTH (Region, region);
- SET_CACHE_POS (ChordObject, chord_object);
SET_CACHE_POS (ScaleObject, scale_object);
SET_CACHE_POS (Marker, marker);
- SET_CACHE_POS (AutomationPoint, automation_point);
#undef SET_CACHE_POS_W_LENGTH
#undef SET_CACHE_POS
@@ -175,14 +169,9 @@ timeline_selections_reset_transient_poses (
RESET_TRANS_POS_W_LENGTH (
REGION, Region, region);
RESET_TRANS_POS (
- CHORD_OBJECT, ChordObject, chord_object);
- RESET_TRANS_POS (
SCALE_OBJECT, ScaleObject, scale_object);
RESET_TRANS_POS (
MARKER, Marker, marker);
- RESET_TRANS_POS (
- AUTOMATION_POINT, AutomationPoint,
- automation_point);
#undef RESET_TRANS_POS_W_LENGTH
#undef RESET_TRANS_POS
@@ -213,12 +202,6 @@ timeline_selections_get_start_pos (
ts, Region, region, start_pos,
transient, before, widget);
ARRANGER_OBJ_SET_GIVEN_POS_TO (
- ts, AutomationPoint, automation_point, pos,
- transient, before, widget);
- ARRANGER_OBJ_SET_GIVEN_POS_TO (
- ts, ChordObject, chord_object, pos,
- transient, before, widget);
- ARRANGER_OBJ_SET_GIVEN_POS_TO (
ts, ScaleObject, scale_object, pos,
transient, before, widget);
ARRANGER_OBJ_SET_GIVEN_POS_TO (
@@ -250,12 +233,6 @@ timeline_selections_get_end_pos (
ts, Region, region, start_pos,
transient, after, widget);
ARRANGER_OBJ_SET_GIVEN_POS_TO (
- ts, AutomationPoint, automation_point, pos,
- transient, after, widget);
- ARRANGER_OBJ_SET_GIVEN_POS_TO (
- ts, ChordObject, chord_object, pos,
- transient, after, widget);
- ARRANGER_OBJ_SET_GIVEN_POS_TO (
ts, ScaleObject, scale_object, pos,
transient, after, widget);
ARRANGER_OBJ_SET_GIVEN_POS_TO (
@@ -285,12 +262,6 @@ timeline_selections_get_first_object (
ts, Region, region, start_pos,
transient, before, widget);
ARRANGER_OBJ_SET_GIVEN_POS_TO (
- ts, AutomationPoint, automation_point, pos,
- transient, before, widget);
- ARRANGER_OBJ_SET_GIVEN_POS_TO (
- ts, ChordObject, chord_object, pos,
- transient, before, widget);
- ARRANGER_OBJ_SET_GIVEN_POS_TO (
ts, ScaleObject, scale_object, pos,
transient, before, widget);
ARRANGER_OBJ_SET_GIVEN_POS_TO (
@@ -321,12 +292,6 @@ timeline_selections_get_last_object (
ts, Region, region, start_pos,
transient, after, widget);
ARRANGER_OBJ_SET_GIVEN_POS_TO (
- ts, AutomationPoint, automation_point, pos,
- transient, after, widget);
- ARRANGER_OBJ_SET_GIVEN_POS_TO (
- ts, ChordObject, chord_object, pos,
- transient, after, widget);
- ARRANGER_OBJ_SET_GIVEN_POS_TO (
ts, ScaleObject, scale_object, pos,
transient, after, widget);
ARRANGER_OBJ_SET_GIVEN_POS_TO (
@@ -372,18 +337,6 @@ timeline_selections_get_highest_track (
region = ts->regions[i]->obj_info.main;
CHECK_POS (region->lane->track);
}
- AutomationPoint * ap;
- for (int i = 0; i < ts->num_automation_points; i++)
- {
- if (transient)
- ap =
- automation_point_get_main_trans_automation_point (
- ts->automation_points[i]);
- else
- ap = automation_point_get_main_automation_point (
- ts->automation_points[i]);
- CHECK_POS (ap->at->track);
- }
CHECK_POS (P_CHORD_TRACK);
return track;
@@ -426,16 +379,6 @@ timeline_selections_get_lowest_track (
region = ts->regions[i]->obj_info.main;
CHECK_POS (region->lane->track);
}
- AutomationPoint * ap;
- for (int i = 0; i < ts->num_automation_points; i++)
- {
- if (transient)
- ap =
- automation_point_get_main_trans_automation_point (ts->automation_points[i]);
- else
- ap = automation_point_get_main_automation_point (ts->automation_points[i]);
- CHECK_POS (ap->at->track);
- }
CHECK_POS (P_CHORD_TRACK);
return track;
@@ -456,13 +399,8 @@ timeline_selections_get_lowest_track (
DEFINE_ADD_OBJECT (REGION, Region, region);
DEFINE_ADD_OBJECT (
- CHORD_OBJECT, ChordObject, chord_object);
-DEFINE_ADD_OBJECT (
SCALE_OBJECT, ScaleObject, scale_object);
DEFINE_ADD_OBJECT (MARKER, Marker, marker);
-DEFINE_ADD_OBJECT (
- AUTOMATION_POINT, AutomationPoint,
- automation_point);
#undef DEFINE_ADD_OBJECT
@@ -477,13 +415,8 @@ DEFINE_ADD_OBJECT (
DEFINE_REMOVE_OBJ (REGION, Region, region);
DEFINE_REMOVE_OBJ (
- CHORD_OBJECT, ChordObject, chord_object);
-DEFINE_REMOVE_OBJ (
SCALE_OBJECT, ScaleObject, scale_object);
DEFINE_REMOVE_OBJ (MARKER, Marker, marker);
-DEFINE_REMOVE_OBJ (
- AUTOMATION_POINT, AutomationPoint,
- automation_point);
#undef DEFINE_REMOVE_OBJ
@@ -500,13 +433,8 @@ DEFINE_REMOVE_OBJ (
DEFINE_CONTAINS_OBJ (REGION, Region, region);
DEFINE_CONTAINS_OBJ (
- CHORD_OBJECT, ChordObject, chord_object);
-DEFINE_CONTAINS_OBJ (
SCALE_OBJECT, ScaleObject, scale_object);
DEFINE_CONTAINS_OBJ (MARKER, Marker, marker);
-DEFINE_CONTAINS_OBJ (
- AUTOMATION_POINT, AutomationPoint,
- automation_point);
#undef DEFINE_CONTAINS_OBJ
@@ -554,14 +482,9 @@ timeline_selections_set_to_transient_poses (
SET_TO_TRANS_POS_W_LENGTH (
REGION, Region, region);
SET_TO_TRANS_POS (
- CHORD_OBJECT, ChordObject, chord_object);
- SET_TO_TRANS_POS (
SCALE_OBJECT, ScaleObject, scale_object);
SET_TO_TRANS_POS (
MARKER, Marker, marker);
- SET_TO_TRANS_POS (
- AUTOMATION_POINT, AutomationPoint,
- automation_point);
#undef SET_TO_TRANS_POS_W_LENGTH
#undef SET_TO_TRANS_POS
@@ -598,11 +521,6 @@ timeline_selections_clear (
TL_REMOVE_OBJS (
REGION, Region, region);
TL_REMOVE_OBJS (
- AUTOMATION_POINT, AutomationPoint,
- automation_point);
- TL_REMOVE_OBJS (
- CHORD_OBJECT, ChordObject, chord_object);
- TL_REMOVE_OBJS (
SCALE_OBJECT, ScaleObject, scale_object);
TL_REMOVE_OBJS (
MARKER, Marker, marker);
@@ -614,13 +532,13 @@ timeline_selections_clear (
* Clone the struct for copying, undoing, etc.
*/
TimelineSelections *
-timeline_selections_clone ()
+timeline_selections_clone (
+ TimelineSelections * src)
{
TimelineSelections * new_ts =
calloc (1, sizeof (TimelineSelections));
int i;
- TimelineSelections * src = TL_SELECTIONS;
#define TL_CLONE_OBJS(caps,cc,sc) \
cc * sc, * new_##sc; \
@@ -637,11 +555,6 @@ timeline_selections_clone ()
TL_CLONE_OBJS (
REGION, Region, region);
TL_CLONE_OBJS (
- AUTOMATION_POINT, AutomationPoint,
- automation_point);
- TL_CLONE_OBJS (
- CHORD_OBJECT, ChordObject, chord_object);
- TL_CLONE_OBJS (
SCALE_OBJECT, ScaleObject, scale_object);
TL_CLONE_OBJS (
MARKER, Marker, marker);
@@ -660,15 +573,6 @@ void
timeline_selections_set_to_transient_values (
TimelineSelections * ts)
{
- AutomationPoint * ap;
- for (int i = 0; i < ts->num_automation_points;
- i++)
- {
- ap = ts->automation_points[i];
- ap->fvalue =
- automation_point_get_main_trans_automation_point (
- ap)->fvalue;
- }
}
@@ -704,10 +608,6 @@ timeline_selections_add_ticks (
UPDATE_TL_POSES (
Region, region);
UPDATE_TL_POSES (
- AutomationPoint, automation_point);
- UPDATE_TL_POSES (
- ChordObject, chord_object);
- UPDATE_TL_POSES (
ScaleObject, scale_object);
UPDATE_TL_POSES (
Marker, marker);
@@ -796,23 +696,6 @@ timeline_selections_paste_to_pos (
cp->lane->track, cp, 0, F_GEN_NAME,
F_GEN_WIDGET);
}
- for (i = 0; i < ts->num_automation_points; i++)
- {
- AutomationPoint * ap =
- ts->automation_points[i];
-
- curr_ticks = position_to_ticks (&ap->pos);
- position_from_ticks (&ap->pos,
- pos_ticks + DIFF);
- }
- for (i = 0; i < ts->num_chord_objects; i++)
- {
- ChordObject * chord = ts->chord_objects[i];
-
- curr_ticks = position_to_ticks (&chord->pos);
- position_from_ticks (&chord->pos,
- pos_ticks + DIFF);
- }
for (i = 0; i < ts->num_scale_objects; i++)
{
ScaleObject * scale = ts->scale_objects[i];
@@ -825,6 +708,25 @@ timeline_selections_paste_to_pos (
}
void
+timeline_selections_free_full (
+ TimelineSelections * self)
+{
+ int i;
+ for (i = 0; i < self->num_regions; i++)
+ {
+ region_free (self->regions[i]);
+ }
+ for (i = 0; i < self->num_markers; i++)
+ {
+ marker_free (self->markers[i]);
+ }
+ for (i = 0; i < self->num_scale_objects; i++)
+ {
+ scale_object_free (self->scale_objects[i]);
+ }
+}
+
+void
timeline_selections_free (
TimelineSelections * self)
{
diff --git a/src/gui/meson.build b/src/gui/meson.build
index 01dc091..01f0caf 100644
--- a/src/gui/meson.build
+++ b/src/gui/meson.build
@@ -1,3 +1,20 @@
+# Copyright (C) 2019 Alexandros Theodotou <alex at zrythm dot org>
+#
+# This file is part of Zrythm
+#
+# Zrythm is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Affero General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# Zrythm 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 Affero General Public License for more details.
+#
+# You should have received a copy of the GNU Affero General Public License
+# along with Zrythm. If not, see <https://www.gnu.org/licenses/>.
+
gui_srcs = [
'accel.c',
]
diff --git a/src/gui/widgets/arranger.c b/src/gui/widgets/arranger.c
index f5fde4e..0c4b2a9 100644
--- a/src/gui/widgets/arranger.c
+++ b/src/gui/widgets/arranger.c
@@ -34,11 +34,15 @@
#include "gui/widgets/audio_arranger_bg.h"
#include "gui/widgets/audio_clip_editor.h"
#include "gui/widgets/audio_ruler.h"
+#include "gui/widgets/automation_arranger.h"
+#include "gui/widgets/automation_arranger_bg.h"
#include "gui/widgets/automation_curve.h"
#include "gui/widgets/automation_track.h"
#include "gui/widgets/automation_point.h"
#include "gui/widgets/bot_dock_edge.h"
#include "gui/widgets/center_dock.h"
+#include "gui/widgets/chord_arranger.h"
+#include "gui/widgets/chord_arranger_bg.h"
#include "gui/widgets/chord_object.h"
#include "gui/widgets/clip_editor.h"
#include "gui/widgets/color_area.h"
@@ -85,28 +89,53 @@ DEFINE_START_POS
* Useful boilerplate
*/
#define GET_ARRANGER_ALIASES(self) \
- TimelineArrangerWidget * timeline = NULL; \
- MidiArrangerWidget * midi_arranger = NULL; \
- MidiModifierArrangerWidget * midi_modifier_arranger = NULL; \
+ TimelineArrangerWidget * timeline_arranger = \
+ NULL; \
+ MidiArrangerWidget * midi_arranger = NULL; \
+ MidiModifierArrangerWidget * \
+ midi_modifier_arranger = NULL; \
AudioArrangerWidget * audio_arranger = NULL; \
+ ChordArrangerWidget * chord_arranger = NULL; \
+ AutomationArrangerWidget * automation_arranger = \
+ NULL; \
if (ARRANGER_IS_MIDI (self)) \
{ \
midi_arranger = Z_MIDI_ARRANGER_WIDGET (self); \
} \
else if (ARRANGER_IS_TIMELINE (self)) \
{ \
- timeline = Z_TIMELINE_ARRANGER_WIDGET (self); \
+ timeline_arranger = \
+ Z_TIMELINE_ARRANGER_WIDGET (self); \
} \
else if (Z_IS_AUDIO_ARRANGER_WIDGET (self)) \
{ \
- audio_arranger = Z_AUDIO_ARRANGER_WIDGET (self); \
+ audio_arranger = \
+ Z_AUDIO_ARRANGER_WIDGET (self); \
} \
else if (ARRANGER_IS_MIDI_MODIFIER (self)) \
{ \
midi_modifier_arranger = \
Z_MIDI_MODIFIER_ARRANGER_WIDGET (self); \
+ } \
+ else if (Z_IS_CHORD_ARRANGER_WIDGET (self)) \
+ { \
+ chord_arranger = \
+ Z_CHORD_ARRANGER_WIDGET (self); \
+ } \
+ else if (Z_IS_AUTOMATION_ARRANGER_WIDGET (self)) \
+ { \
+ automation_arranger = \
+ Z_AUTOMATION_ARRANGER_WIDGET (self); \
}
+#define FORALL_ARRANGERS(func) \
+ func (timeline); \
+ func (midi); \
+ func (audio); \
+ func (automation); \
+ func (midi_modifier); \
+ func (chord); \
+
ArrangerWidgetPrivate *
arranger_widget_get_private (ArrangerWidget * self)
{
@@ -124,11 +153,18 @@ get_child_position (GtkOverlay *self,
{
GET_ARRANGER_ALIASES (self);
+#define ELIF_ARR_SET_ALLOCATION(sc) \
+ if (sc##_arranger) \
+ { \
+ sc##_arranger_widget_set_allocation ( \
+ sc##_arranger, widget, allocation); \
+ }
+
if (Z_IS_ARRANGER_PLAYHEAD_WIDGET (widget))
{
/* note: -1 (half the width of the playhead
* widget */
- if (timeline)
+ if (timeline_arranger)
allocation->x =
ui_pos_to_px_timeline (
&TRANSPORT->playhead_pos,
@@ -149,34 +185,9 @@ get_child_position (GtkOverlay *self,
gtk_widget_get_allocated_height (
GTK_WIDGET (self));
}
- else if (midi_arranger)
- {
- midi_arranger_widget_set_allocation (
- midi_arranger,
- widget,
- allocation);
- }
- else if (timeline)
- {
- timeline_arranger_widget_set_allocation (
- timeline,
- widget,
- allocation);
- }
- else if (midi_modifier_arranger)
- {
- midi_modifier_arranger_widget_set_allocation (
- midi_modifier_arranger,
- widget,
- allocation);
- }
- else if (audio_arranger)
- {
- audio_arranger_widget_set_allocation (
- audio_arranger,
- widget,
- allocation);
- }
+ FORALL_ARRANGERS (ELIF_ARR_SET_ALLOCATION)
+#undef ELIF_ARR_SET_ALLOCATION
+
return TRUE;
}
@@ -433,19 +444,14 @@ arranger_widget_select (
sc##_widget_select ( \
((cc *)child)->widget, select);
- if (timeline)
+ if (timeline_arranger)
{
FIND_ARRAY_AND_NUM (
REGION, region, TL_SELECTIONS);
FIND_ARRAY_AND_NUM (
- CHORD_OBJECT, chord_object, TL_SELECTIONS);
- FIND_ARRAY_AND_NUM (
SCALE_OBJECT, scale_object, TL_SELECTIONS);
FIND_ARRAY_AND_NUM (
MARKER, marker, TL_SELECTIONS);
- FIND_ARRAY_AND_NUM (
- AUTOMATION_POINT, automation_point,
- TL_SELECTIONS);
}
if (midi_arranger)
{
@@ -462,11 +468,23 @@ arranger_widget_select (
FIND_ARRAY_AND_NUM (
MIDI_NOTE, midi_note, MA_SELECTIONS);
}
+ if (chord_arranger)
+ {
+ FIND_ARRAY_AND_NUM (
+ CHORD_OBJECT, chord_object,
+ CHORD_SELECTIONS);
+ }
+ if (automation_arranger)
+ {
+ FIND_ARRAY_AND_NUM (
+ AUTOMATION_POINT, automation_point,
+ AUTOMATION_SELECTIONS);
+ }
if (select && !append)
{
/* deselect existing selections */
- if (timeline)
+ if (timeline_arranger)
timeline_selections_clear (
TL_SELECTIONS);
else if (midi_arranger)
@@ -573,25 +591,15 @@ arranger_widget_select_all (
{
GET_ARRANGER_ALIASES (self);
- if (midi_arranger)
- {
- midi_arranger_widget_select_all (
- midi_arranger, select);
- }
- else if (timeline)
- {
- timeline_arranger_widget_select_all (
- timeline, select);
- }
- else if (midi_modifier_arranger)
- {
- midi_modifier_arranger_widget_select_all (
- midi_modifier_arranger, select);
+#define ARR_SELECT_ALL(sc) \
+ if (sc##_arranger) \
+ { \
+ sc##_arranger_widget_select_all ( \
+ sc##_arranger, select); \
}
- else if (audio_arranger)
- {
+ FORALL_ARRANGERS (ARR_SELECT_ALL);
- }
+#undef ARR_SELECT_ALL
}
static void
@@ -602,25 +610,14 @@ show_context_menu (
{
GET_ARRANGER_ALIASES (self);
- if (midi_arranger)
- {
- midi_arranger_widget_show_context_menu (
- midi_arranger, x, y);
- }
- else if (timeline)
- {
- timeline_arranger_widget_show_context_menu (
- timeline, x, y);
- }
- else if (audio_arranger)
- {
- /*audio_arranger_widget_show_context_menu (*/
- /*Z_AUDIO_ARRANGER_WIDGET (self));*/
- }
- else if (midi_modifier_arranger)
- {
+#define SHOW_CONTEXT_MENU(sc) \
+ if (sc##_arranger) \
+ sc##_arranger_widget_show_context_menu ( \
+ sc##_arranger, x, y)
- }
+ FORALL_ARRANGERS (SHOW_CONTEXT_MENU);
+
+#undef SHOW_CONTEXT_MENU
}
static void
@@ -640,7 +637,6 @@ static void
auto_scroll (ArrangerWidget * self)
{
return;
- g_message ("AUTO SCROLL");
ARRANGER_WIDGET_GET_PRIVATE (self);
GET_ARRANGER_ALIASES(self);
GtkScrolledWindow *scrolled =
@@ -656,7 +652,7 @@ auto_scroll (ArrangerWidget * self)
ar_prv->action ==
UI_OVERLAY_ACTION_MOVING_LINK);
};
- if (timeline)
+ if (timeline_arranger)
{
}
@@ -668,6 +664,14 @@ auto_scroll (ArrangerWidget * self)
{
}
+ if (automation_arranger)
+ {
+
+ }
+ if (chord_arranger)
+ {
+
+ }
}
static gboolean
@@ -713,21 +717,14 @@ on_key_release_action (
ar_prv->action =
UI_OVERLAY_ACTION_MOVING;
- if (midi_arranger)
- midi_arranger_widget_update_visibility (
- midi_arranger);
- if (timeline)
- timeline_arranger_widget_update_visibility (
- timeline);
- if (midi_modifier_arranger)
- {
- midi_modifier_arranger_widget_update_visibility (
- midi_modifier_arranger);
- }
- if (audio_arranger)
- {
+#define UPDATE_VISIBILITY(sc) \
+ if (sc##_arranger) \
+ sc##_arranger_widget_update_visibility ( \
+ sc##_arranger)
- }
+ FORALL_ARRANGERS (UPDATE_VISIBILITY);
+
+#undef UPDATE_VISIBILITY
arranger_widget_refresh_cursor (
self);
@@ -817,7 +814,7 @@ on_key_action (
/*UNDO_MANAGER, shift_right_action);*/
}
}
- if (timeline)
+ if (timeline_arranger)
{
/* TODO */
@@ -830,6 +827,10 @@ on_key_action (
{
}
+ if (chord_arranger)
+ {}
+ if (automation_arranger)
+ {}
if (ar_prv->action ==
UI_OVERLAY_ACTION_STARTING_MOVING)
@@ -858,9 +859,9 @@ on_key_action (
if (midi_modifier_arranger)
midi_modifier_arranger_widget_update_visibility (
midi_modifier_arranger);
- else if (timeline)
+ else if (timeline_arranger)
timeline_arranger_widget_update_visibility (
- timeline);
+ timeline_arranger);
arranger_widget_refresh_cursor (
self);
@@ -929,59 +930,52 @@ create_item (ArrangerWidget * self,
NULL, &pos, NULL, NULL,
ar_prv->snap_grid);
- if (timeline)
+ if (timeline_arranger)
{
/* figure out if we are creating a region or
* automation point */
at =
- timeline_arranger_widget_get_automation_track_at_y (timeline, start_y);
+ timeline_arranger_widget_get_automation_track_at_y (
+ timeline_arranger, start_y);
if (!at)
track =
timeline_arranger_widget_get_track_at_y (
- timeline, start_y);
+ timeline_arranger, start_y);
/* creating automation point */
if (at)
{
- timeline_arranger_widget_create_ap (
- timeline,
- at,
- &pos,
- start_y);
+ timeline_arranger_widget_create_region (
+ timeline_arranger, track, NULL, at,
+ &pos);
}
/* double click inside a track */
else if (track)
{
TrackLane * lane =
timeline_arranger_widget_get_track_lane_at_y (
- timeline, start_y);
+ timeline_arranger, start_y);
switch (track->type)
{
case TRACK_TYPE_INSTRUMENT:
case TRACK_TYPE_AUDIO:
timeline_arranger_widget_create_region (
- timeline,
- track,
- lane,
- &pos);
+ timeline_arranger, track,
+ lane, NULL, &pos);
break;
case TRACK_TYPE_MASTER:
break;
case TRACK_TYPE_CHORD:
timeline_arranger_widget_create_chord_or_scale (
- timeline,
- track,
- start_y,
- &pos);
+ timeline_arranger, track,
+ start_y, &pos);
case TRACK_TYPE_BUS:
break;
case TRACK_TYPE_GROUP:
break;
case TRACK_TYPE_MARKER:
timeline_arranger_widget_create_marker (
- timeline,
- track,
- &pos);
+ timeline_arranger, track, &pos);
break;
default:
/* TODO */
@@ -1015,6 +1009,10 @@ create_item (ArrangerWidget * self,
{
}
+ if (chord_arranger)
+ { }
+ if (automation_arranger)
+ { }
/* something is (likely) added so reallocate */
gtk_widget_queue_allocate (GTK_WIDGET (self));
@@ -1063,7 +1061,7 @@ drag_begin (GtkGestureDrag * gesture,
if (midi_arranger)
{
midi_note_widget =
- midi_arranger_widget_get_hit_midi_note (
+ midi_arranger_widget_get_hit_note (
midi_arranger, start_x, start_y);
}
else if (audio_arranger)
@@ -1075,26 +1073,32 @@ drag_begin (GtkGestureDrag * gesture,
midi_modifier_arranger_widget_get_hit_velocity (
midi_modifier_arranger, start_x, start_y);
}
- else if (timeline)
+ else if (timeline_arranger)
{
rw =
timeline_arranger_widget_get_hit_region (
- timeline, start_x, start_y);
- ac_widget =
- timeline_arranger_widget_get_hit_curve (
- timeline, start_x, start_y);
- ap_widget =
- timeline_arranger_widget_get_hit_ap (
- timeline, start_x, start_y);
- chord_widget =
- timeline_arranger_widget_get_hit_chord (
- timeline, start_x, start_y);
+ timeline_arranger, start_x, start_y);
scale_widget =
timeline_arranger_widget_get_hit_scale (
- timeline, start_x, start_y);
+ timeline_arranger, start_x, start_y);
mw =
timeline_arranger_widget_get_hit_marker (
- timeline, start_x, start_y);
+ timeline_arranger, start_x, start_y);
+ }
+ else if (automation_arranger)
+ {
+ ac_widget =
+ automation_arranger_widget_get_hit_ac (
+ automation_arranger, start_x, start_y);
+ ap_widget =
+ automation_arranger_widget_get_hit_ap (
+ automation_arranger, start_x, start_y);
+ }
+ else if (chord_arranger)
+ {
+ chord_widget =
+ chord_arranger_widget_get_hit_chord (
+ chord_arranger, start_x, start_y);
}
/* if something is hit */
@@ -1113,38 +1117,38 @@ drag_begin (GtkGestureDrag * gesture,
else if (rw)
{
timeline_arranger_widget_on_drag_begin_region_hit (
- timeline, start_x, rw);
+ timeline_arranger, start_x, rw);
}
else if (chord_widget)
{
- timeline_arranger_widget_on_drag_begin_chord_hit (
- timeline, start_x, chord_widget);
+ chord_arranger_widget_on_drag_begin_chord_hit (
+ chord_arranger, start_x, chord_widget);
}
else if (scale_widget)
{
timeline_arranger_widget_on_drag_begin_scale_hit (
- timeline, start_x, scale_widget);
+ timeline_arranger, start_x, scale_widget);
}
else if (ap_widget)
{
- timeline_arranger_widget_on_drag_begin_ap_hit (
- timeline, start_x, ap_widget);
+ automation_arranger_widget_on_drag_begin_ap_hit (
+ automation_arranger, start_x, ap_widget);
}
else if (ac_widget)
{
- timeline->start_ac =
+ automation_arranger->start_ac =
ac_widget->ac;
}
else if (vel_widget)
{
- midi_modifier_arranger_on_drag_begin_vel_hit (
- midi_modifier_arranger,
- vel_widget, start_y);
+ midi_modifier_arranger_widget_on_drag_begin_velocity_hit (
+ midi_modifier_arranger, start_y,
+ vel_widget);
}
else if (mw)
{
timeline_arranger_widget_on_drag_begin_marker_hit (
- timeline, start_x, mw);
+ timeline_arranger, start_x, mw);
}
}
else /* nothing hit */
@@ -1164,11 +1168,10 @@ drag_begin (GtkGestureDrag * gesture,
/* if timeline, set either selecting
* objects or selecting range */
- if (timeline)
+ if (timeline_arranger)
{
timeline_arranger_widget_set_select_type (
- timeline,
- start_y);
+ timeline_arranger, start_y);
}
}
else if (P_TOOL == TOOL_EDIT)
@@ -1218,7 +1221,7 @@ drag_begin (GtkGestureDrag * gesture,
/* set start pos */
position_set_to_bar (
&ar_prv->earliest_obj_start_pos, 2000);
- if (timeline &&
+ if (timeline_arranger &&
timeline_selections_has_any (
TL_SELECTIONS))
{
@@ -1374,10 +1377,10 @@ drag_update (
{
case UI_OVERLAY_ACTION_SELECTING:
/* find and select objects inside selection */
- if (timeline)
+ if (timeline_arranger)
{
timeline_arranger_widget_select (
- timeline,
+ timeline_arranger,
offset_x,
offset_y,
F_NO_DELETE);
@@ -1406,48 +1409,30 @@ drag_update (
case UI_OVERLAY_ACTION_DELETE_SELECTING:
/* find and delete objects inside
* selection */
- if (timeline)
- {
- timeline_arranger_widget_select (
- timeline,
- offset_x,
- offset_y,
- 1);
- }
- else if (midi_arranger)
- {
- midi_arranger_widget_select (
- midi_arranger,
- offset_x,
- offset_y,
- 1);
- }
- else if (midi_modifier_arranger)
- {
- midi_modifier_arranger_widget_select (
- midi_modifier_arranger,
- offset_x,
- offset_y,
- 1);
- }
- else if (audio_arranger)
- {
- /* TODO */
- }
+#define DO_SELECT(sc) \
+ if (sc##_arranger) \
+ { \
+ sc##_arranger_widget_select ( \
+ sc##_arranger, offset_x, offset_y, 1); \
+ }
+
+ FORALL_ARRANGERS (DO_SELECT);
+
+#undef DO_SELECT
break;
case UI_OVERLAY_ACTION_RESIZING_L:
/* snap selections based on new pos */
- if (timeline)
+ if (timeline_arranger)
{
timeline_arranger_widget_update_visibility (
- timeline);
+ timeline_arranger);
int ret =
timeline_arranger_widget_snap_regions_l (
- timeline,
+ timeline_arranger,
&ar_prv->curr_pos, 1);
if (!ret)
timeline_arranger_widget_snap_regions_l (
- timeline,
+ timeline_arranger,
&ar_prv->curr_pos, 0);
}
else if (midi_arranger)
@@ -1472,22 +1457,22 @@ drag_update (
break;
case UI_OVERLAY_ACTION_RESIZING_R:
case UI_OVERLAY_ACTION_CREATING_RESIZING_R:
- if (timeline)
+ if (timeline_arranger)
{
- if (timeline->resizing_range)
+ if (timeline_arranger->resizing_range)
timeline_arranger_widget_snap_range_r (
&ar_prv->curr_pos);
else
{
timeline_arranger_widget_update_visibility (
- timeline);
+ timeline_arranger);
int ret =
timeline_arranger_widget_snap_regions_r (
- timeline,
+ timeline_arranger,
&ar_prv->curr_pos, 1);
if (!ret)
timeline_arranger_widget_snap_regions_r (
- timeline,
+ timeline_arranger,
&ar_prv->curr_pos, 0);
}
}
@@ -1520,16 +1505,16 @@ drag_update (
}
case UI_OVERLAY_ACTION_MOVING:
case UI_OVERLAY_ACTION_CREATING_MOVING:
- if (timeline)
+ if (timeline_arranger)
{
timeline_arranger_widget_update_visibility (
- timeline);
+ timeline_arranger);
timeline_arranger_widget_move_items_x (
- timeline,
+ timeline_arranger,
ar_prv->adj_ticks_diff,
F_NOT_COPY_MOVING);
timeline_arranger_widget_move_items_y (
- timeline,
+ timeline_arranger,
offset_y);
}
else if (midi_arranger)
@@ -1549,16 +1534,16 @@ drag_update (
}
break;
case UI_OVERLAY_ACTION_MOVING_COPY:
- if (timeline)
+ if (timeline_arranger)
{
timeline_arranger_widget_update_visibility (
- timeline);
+ timeline_arranger);
timeline_arranger_widget_move_items_x (
- timeline,
+ timeline_arranger,
ar_prv->adj_ticks_diff,
F_COPY_MOVING);
timeline_arranger_widget_move_items_y (
- timeline,
+ timeline_arranger,
offset_y);
}
else if (midi_arranger)
@@ -1587,7 +1572,7 @@ drag_update (
break;
case UI_OVERLAY_ACTION_RAMPING:
/* find and select objects inside selection */
- if (timeline)
+ if (timeline_arranger)
{
/* TODO */
}
@@ -1630,25 +1615,14 @@ drag_end (GtkGestureDrag *gesture,
GET_ARRANGER_ALIASES (self);
- if (midi_arranger)
- {
- midi_arranger_widget_on_drag_end (
- midi_arranger);
- }
- else if (timeline)
- {
- timeline_arranger_widget_on_drag_end (
- timeline);
- }
- else if (midi_modifier_arranger)
- {
- midi_modifier_arranger_widget_on_drag_end (
- midi_modifier_arranger);
- }
- else if (audio_arranger)
- {
- /* TODO */
- }
+#define ON_DRAG_END(sc) \
+ if (sc##_arranger) \
+ sc##_arranger_widget_on_drag_end ( \
+ sc##_arranger)
+
+ FORALL_ARRANGERS (ON_DRAG_END);
+
+#undef ON_DRAG_END
/* if clicked on nothing */
if (ar_prv->action ==
@@ -1684,7 +1658,7 @@ arranger_widget_pos_to_px (
{
GET_ARRANGER_ALIASES (self);
- if (timeline)
+ if (timeline_arranger)
return ui_pos_to_px_timeline (
pos, use_padding);
else if (midi_arranger || midi_modifier_arranger)
@@ -1693,6 +1667,14 @@ arranger_widget_pos_to_px (
else if (audio_arranger)
return ui_pos_to_px_audio_clip_editor (
pos, use_padding);
+ else if (chord_arranger)
+ {
+ return -1;
+ }
+ else if (automation_arranger)
+ {
+ return -1;
+ }
return -1;
}
@@ -1706,7 +1688,7 @@ arranger_widget_get_scrolled_window (
{
GET_ARRANGER_ALIASES (self);
- if (timeline)
+ if (timeline_arranger)
return MW_CENTER_DOCK->timeline_scroll;
else if (midi_arranger)
return MW_PIANO_ROLL->arranger_scroll;
@@ -1714,6 +1696,10 @@ arranger_widget_get_scrolled_window (
return MW_PIANO_ROLL->modifier_arranger_scroll;
else if (audio_arranger)
return MW_AUDIO_CLIP_EDITOR->arranger_scroll;
+ else if (chord_arranger)
+ return NULL;
+ else if (automation_arranger)
+ return NULL;
return NULL;
}
@@ -1747,8 +1733,6 @@ on_scroll (GtkWidget *widget,
ArrangerWidget * self)
{
GET_ARRANGER_ALIASES (widget);
- g_message ("dx %f dy %f", event->delta_x,
- event->delta_y);
if (!(event->state & GDK_CONTROL_MASK))
return FALSE;
@@ -1764,13 +1748,17 @@ on_scroll (GtkWidget *widget,
RulerWidget * ruler = NULL;
RulerWidgetPrivate * rw_prv;
- if (timeline)
+ if (timeline_arranger)
ruler = Z_RULER_WIDGET (MW_RULER);
else if (midi_modifier_arranger ||
midi_arranger)
ruler = Z_RULER_WIDGET (MIDI_RULER);
else if (audio_arranger)
ruler = Z_RULER_WIDGET (AUDIO_RULER);
+ else if (chord_arranger)
+ ruler = NULL;
+ else if (automation_arranger)
+ ruler = NULL;
rw_prv = ruler_widget_get_private (ruler);
@@ -1806,7 +1794,7 @@ on_scroll (GtkWidget *widget,
self, &cursor_pos, 1);
/* refresh relevant widgets */
- if (timeline)
+ if (timeline_arranger)
timeline_minimap_widget_refresh (
MW_TIMELINE_MINIMAP);
@@ -1871,9 +1859,9 @@ on_grab_broken (GtkWidget *widget,
GdkEvent *event,
gpointer user_data)
{
- GdkEventGrabBroken * ev =
- (GdkEventGrabBroken *) event;
- g_message ("arranger grab broken");
+ /*GdkEventGrabBroken * ev =*/
+ /*(GdkEventGrabBroken *) event;*/
+ g_warning ("arranger grab broken");
return FALSE;
}
@@ -1898,14 +1886,14 @@ arranger_widget_setup (
midi_arranger_widget_setup (
midi_arranger);
}
- else if (timeline)
+ else if (timeline_arranger)
{
ar_prv->bg = Z_ARRANGER_BG_WIDGET (
timeline_bg_widget_new (
Z_RULER_WIDGET (MW_RULER),
self));
timeline_arranger_widget_setup (
- timeline);
+ timeline_arranger);
}
else if (midi_modifier_arranger)
{
@@ -1925,6 +1913,24 @@ arranger_widget_setup (
audio_arranger_widget_setup (
audio_arranger);
}
+ else if (chord_arranger)
+ {
+ ar_prv->bg = Z_ARRANGER_BG_WIDGET (
+ chord_arranger_bg_widget_new (
+ Z_RULER_WIDGET (MIDI_RULER),
+ self));
+ chord_arranger_widget_setup (
+ chord_arranger);
+ }
+ else if (automation_arranger)
+ {
+ ar_prv->bg = Z_ARRANGER_BG_WIDGET (
+ chord_arranger_bg_widget_new (
+ Z_RULER_WIDGET (MIDI_RULER),
+ self));
+ automation_arranger_widget_setup (
+ automation_arranger);
+ }
gtk_container_add (
GTK_CONTAINER (self),
GTK_WIDGET (ar_prv->bg));
@@ -2007,7 +2013,7 @@ arranger_widget_px_to_pos (
{
GET_ARRANGER_ALIASES (self);
- if (timeline)
+ if (timeline_arranger)
ui_px_to_pos_timeline (
px, pos, has_padding);
else if (midi_arranger)
@@ -2019,6 +2025,10 @@ arranger_widget_px_to_pos (
else if (audio_arranger)
ui_px_to_pos_audio_clip_editor (
px, pos, has_padding);
+ else if (chord_arranger)
+ {}
+ else if (automation_arranger)
+ {}
}
void
@@ -2034,38 +2044,14 @@ arranger_widget_refresh_cursor (
ArrangerCursor ac = ARRANGER_CURSOR_SELECT;
- if (timeline)
- {
- ac =
- timeline_arranger_widget_get_cursor (
- timeline,
- ar_prv->action,
- P_TOOL);
- }
- if (midi_arranger)
- {
- ac =
- midi_arranger_widget_get_cursor (
- midi_arranger,
- ar_prv->action,
- P_TOOL);
- }
- if (audio_arranger)
- {
- ac =
- audio_arranger_widget_get_cursor (
- audio_arranger,
- ar_prv->action,
- P_TOOL);
- }
- if (midi_modifier_arranger)
- {
- ac =
- midi_modifier_arranger_widget_get_cursor (
- midi_modifier_arranger,
- ar_prv->action,
- P_TOOL);
- }
+#define GET_CURSOR(sc) \
+ if (sc##_arranger) \
+ ac = \
+ sc##_arranger_widget_get_cursor ( \
+ sc##_arranger, ar_prv->action, \
+ P_TOOL)
+
+ FORALL_ARRANGERS (GET_CURSOR);
arranger_widget_set_cursor (
self, ac);
@@ -2095,12 +2081,12 @@ arranger_widget_refresh (
midi_arranger_widget_refresh_children (
midi_arranger);
}
- else if (timeline)
+ else if (timeline_arranger)
{
timeline_arranger_widget_set_size (
- timeline);
+ timeline_arranger);
timeline_arranger_widget_refresh_children (
- timeline);
+ timeline_arranger);
}
else if (midi_modifier_arranger)
{
@@ -2123,6 +2109,12 @@ arranger_widget_refresh (
audio_arranger);
}
+ else if (chord_arranger)
+ {
+ }
+ else if (automation_arranger)
+ {
+ }
if (ar_prv->bg)
{
@@ -2134,12 +2126,14 @@ arranger_widget_refresh (
}
static void
-arranger_widget_class_init (ArrangerWidgetClass * _klass)
+arranger_widget_class_init (
+ ArrangerWidgetClass * _klass)
{
}
static void
-arranger_widget_init (ArrangerWidget *self)
+arranger_widget_init (
+ ArrangerWidget *self)
{
GET_PRIVATE;
diff --git a/src/gui/widgets/audio_arranger.c b/src/gui/widgets/audio_arranger.c
index f5e5337..3ea1a9c 100644
--- a/src/gui/widgets/audio_arranger.c
+++ b/src/gui/widgets/audio_arranger.c
@@ -163,7 +163,10 @@ audio_arranger_widget_get_cursor (
* To be called from parent on right click.
*/
void
-audio_arranger_widget_show_context_menu (AudioArrangerWidget * self)
+audio_arranger_widget_show_context_menu (
+ AudioArrangerWidget * self,
+ gdouble x,
+ gdouble y)
{
GtkWidget *menu, *menuitem;
@@ -194,6 +197,53 @@ audio_arranger_widget_setup (
-1);
}
+void
+audio_arranger_widget_select_all (
+ AudioArrangerWidget * self,
+ int select)
+{
+}
+
+/**
+ * Called when in selection mode.
+ *
+ * Called by arranger widget during drag_update to find and
+ * select the midi notes enclosed in the selection area.
+ *
+ * @param[in] delete If this is a select-delete
+ * operation
+ */
+void
+audio_arranger_widget_select (
+ AudioArrangerWidget * self,
+ double offset_x,
+ double offset_y,
+ int delete)
+{
+}
+
+/**
+ * Called on drag end.
+ *
+ * Sets default cursors back and sets the start midi note
+ * to NULL if necessary.
+ */
+void
+audio_arranger_widget_on_drag_end (
+ AudioArrangerWidget * self)
+{
+}
+
+/**
+ * Sets transient notes and actual notes
+ * visibility based on the current action.
+ */
+void
+audio_arranger_widget_update_visibility (
+ AudioArrangerWidget * self)
+{
+}
+
/**
* Readd children.
*/
diff --git a/src/gui/widgets/automation_arranger.c b/src/gui/widgets/automation_arranger.c
new file mode 100644
index 0000000..5a98a54
--- /dev/null
+++ b/src/gui/widgets/automation_arranger.c
@@ -0,0 +1,961 @@
+/*
+ * Copyright (C) 2018-2019 Alexandros Theodotou <alex at zrythm dot org>
+ *
+ * This file is part of Zrythm
+ *
+ * Zrythm is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Zrythm 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 Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with Zrythm. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+/**
+ * \file
+ *
+ * The automation containing regions and other
+ * objects.
+ */
+
+#include "actions/undoable_action.h"
+#include "actions/create_automation_selections_action.h"
+#include "actions/undo_manager.h"
+#include "actions/duplicate_automation_selections_action.h"
+#include "actions/move_automation_selections_action.h"
+#include "audio/automation_region.h"
+#include "audio/automation_track.h"
+#include "audio/automation_tracklist.h"
+#include "audio/audio_track.h"
+#include "audio/bus_track.h"
+#include "audio/channel.h"
+#include "audio/chord_object.h"
+#include "audio/chord_track.h"
+#include "audio/instrument_track.h"
+#include "audio/marker_track.h"
+#include "audio/master_track.h"
+#include "audio/midi_region.h"
+#include "audio/mixer.h"
+#include "audio/scale_object.h"
+#include "audio/track.h"
+#include "audio/tracklist.h"
+#include "audio/transport.h"
+#include "gui/backend/automation_selections.h"
+#include "gui/widgets/arranger.h"
+#include "gui/widgets/automation_curve.h"
+#include "gui/widgets/automation_track.h"
+#include "gui/widgets/automation_point.h"
+#include "gui/widgets/bot_dock_edge.h"
+#include "gui/widgets/center_dock.h"
+#include "gui/widgets/chord_object.h"
+#include "gui/widgets/color_area.h"
+#include "gui/widgets/inspector.h"
+#include "gui/widgets/main_window.h"
+#include "gui/widgets/marker.h"
+#include "gui/widgets/midi_arranger.h"
+#include "gui/widgets/midi_arranger_bg.h"
+#include "gui/widgets/midi_region.h"
+#include "gui/widgets/piano_roll.h"
+#include "gui/widgets/pinned_tracklist.h"
+#include "gui/widgets/midi_note.h"
+#include "gui/widgets/region.h"
+#include "gui/widgets/scale_object.h"
+#include "gui/widgets/ruler.h"
+#include "gui/widgets/automation_arranger.h"
+#include "gui/widgets/automation_arranger_bg.h"
+#include "gui/widgets/track.h"
+#include "gui/widgets/tracklist.h"
+#include "project.h"
+#include "settings/settings.h"
+#include "utils/arrays.h"
+#include "utils/cairo.h"
+#include "utils/flags.h"
+#include "utils/objects.h"
+#include "utils/ui.h"
+#include "zrythm.h"
+
+#include <gtk/gtk.h>
+
+G_DEFINE_TYPE (AutomationArrangerWidget,
+ automation_arranger_widget,
+ ARRANGER_WIDGET_TYPE)
+
+/**
+ * To be called from get_child_position in parent widget.
+ *
+ * Used to allocate the overlay children.
+ */
+void
+automation_arranger_widget_set_allocation (
+ AutomationArrangerWidget * self,
+ GtkWidget * widget,
+ GdkRectangle * allocation)
+{
+ if (Z_IS_AUTOMATION_POINT_WIDGET (widget))
+ {
+ AutomationPointWidget * ap_widget =
+ Z_AUTOMATION_POINT_WIDGET (widget);
+ AutomationPoint * ap =
+ ap_widget->automation_point;
+ /*Automatable * a = ap->at->automatable;*/
+
+ gint wx, wy;
+ if (!ap->region->at->created ||
+ !ap->region->at->track->bot_paned_visible)
+ return;
+ gtk_widget_translate_coordinates (
+ GTK_WIDGET (ap->region->at->widget),
+ GTK_WIDGET (self),
+ 0, 0, &wx, &wy);
+
+ allocation->x =
+ ui_pos_to_px_automation_editor (&ap->pos, 1) -
+ AP_WIDGET_POINT_SIZE / 2;
+ allocation->y =
+ (wy + automation_point_get_y_in_px (ap)) -
+ AP_WIDGET_POINT_SIZE / 2;
+ allocation->width = AP_WIDGET_POINT_SIZE;
+ allocation->height = AP_WIDGET_POINT_SIZE;
+ }
+ else if (Z_IS_AUTOMATION_CURVE_WIDGET (widget))
+ {
+ AutomationCurveWidget * acw =
+ Z_AUTOMATION_CURVE_WIDGET (widget);
+ AutomationCurve * ac = acw->ac;
+ /*Automatable * a = ap->at->automatable;*/
+
+ gint wx, wy;
+ if (!ac->region->at->created ||
+ !ac->region->at->track->bot_paned_visible)
+ return;
+ gtk_widget_translate_coordinates (
+ GTK_WIDGET (ac->region->at->widget),
+ GTK_WIDGET (self),
+ 0, 0, &wx, &wy);
+ AutomationPoint * prev_ap =
+ automation_region_get_ap_before_curve (
+ ac->region, ac);
+ AutomationPoint * next_ap =
+ automation_region_get_ap_after_curve (
+ ac->region, ac);
+ if (!prev_ap || !next_ap)
+ g_return_if_reached ();
+
+ allocation->x =
+ ui_pos_to_px_automation_editor (
+ &prev_ap->pos,
+ 1) - AC_Y_HALF_PADDING;
+ int prev_y =
+ automation_point_get_y_in_px (prev_ap);
+ int next_y =
+ automation_point_get_y_in_px (next_ap);
+ allocation->y =
+ (wy + (prev_y > next_y ? next_y : prev_y) -
+ AC_Y_HALF_PADDING);
+ allocation->width =
+ (ui_pos_to_px_automation_editor (
+ &next_ap->pos,
+ 1) - allocation->x) + AC_Y_HALF_PADDING;
+ allocation->height =
+ (prev_y > next_y ?
+ prev_y - next_y :
+ next_y - prev_y) + AC_Y_PADDING;
+ }
+}
+
+/**
+ * Returns the appropriate cursor based on the
+ * current hover_x and y.
+ */
+ArrangerCursor
+automation_arranger_widget_get_cursor (
+ AutomationArrangerWidget * self,
+ UiOverlayAction action,
+ Tool tool)
+{
+ ArrangerCursor ac = ARRANGER_CURSOR_SELECT;
+
+ ARRANGER_WIDGET_GET_PRIVATE (self);
+
+ AutomationPointWidget * apw =
+ automation_arranger_widget_get_hit_ap (
+ self,
+ ar_prv->hover_x,
+ ar_prv->hover_y);
+ AutomationCurveWidget * acw =
+ automation_arranger_widget_get_hit_ac (
+ self,
+ ar_prv->hover_x,
+ ar_prv->hover_y);
+
+ int is_hit = apw || acw;
+
+ switch (action)
+ {
+ case UI_OVERLAY_ACTION_NONE:
+ switch (P_TOOL)
+ {
+ case TOOL_SELECT_NORMAL:
+ {
+ if (is_hit)
+ {
+ return ARRANGER_CURSOR_GRAB;
+ }
+ else
+ {
+ /* set cursor to normal */
+ return ARRANGER_CURSOR_SELECT;
+ }
+ }
+ break;
+ case TOOL_SELECT_STRETCH:
+ break;
+ case TOOL_EDIT:
+ ac = ARRANGER_CURSOR_EDIT;
+ break;
+ case TOOL_CUT:
+ ac = ARRANGER_CURSOR_CUT;
+ break;
+ case TOOL_ERASER:
+ ac = ARRANGER_CURSOR_ERASER;
+ break;
+ case TOOL_RAMP:
+ ac = ARRANGER_CURSOR_RAMP;
+ break;
+ case TOOL_AUDITION:
+ ac = ARRANGER_CURSOR_AUDITION;
+ break;
+ }
+ break;
+ case UI_OVERLAY_ACTION_STARTING_DELETE_SELECTION:
+ case UI_OVERLAY_ACTION_DELETE_SELECTING:
+ case UI_OVERLAY_ACTION_ERASING:
+ ac = ARRANGER_CURSOR_ERASER;
+ break;
+ case UI_OVERLAY_ACTION_STARTING_MOVING_COPY:
+ case UI_OVERLAY_ACTION_MOVING_COPY:
+ ac = ARRANGER_CURSOR_GRABBING_COPY;
+ break;
+ case UI_OVERLAY_ACTION_STARTING_MOVING:
+ case UI_OVERLAY_ACTION_MOVING:
+ ac = ARRANGER_CURSOR_GRABBING;
+ break;
+ case UI_OVERLAY_ACTION_STARTING_MOVING_LINK:
+ case UI_OVERLAY_ACTION_MOVING_LINK:
+ ac = ARRANGER_CURSOR_GRABBING_LINK;
+ break;
+ case UI_OVERLAY_ACTION_RESIZING_L:
+ ac = ARRANGER_CURSOR_RESIZING_L;
+ break;
+ case UI_OVERLAY_ACTION_RESIZING_R:
+ ac = ARRANGER_CURSOR_RESIZING_R;
+ break;
+ default:
+ ac = ARRANGER_CURSOR_SELECT;
+ break;
+ }
+
+ return ac;
+}
+
+#define GET_HIT_WIDGET(caps,cc,sc) \
+cc##Widget * \
+automation_arranger_widget_get_hit_##sc ( \
+ AutomationArrangerWidget * self, \
+ double x, \
+ double y) \
+{ \
+ GtkWidget * widget = \
+ ui_get_hit_child ( \
+ GTK_CONTAINER (self), x, y, \
+ caps##_WIDGET_TYPE); \
+ if (widget) \
+ { \
+ return Z_##caps##_WIDGET (widget); \
+ } \
+ return NULL; \
+}
+
+GET_HIT_WIDGET (
+ AUTOMATION_POINT, AutomationPoint, ap);
+GET_HIT_WIDGET (
+ AUTOMATION_CURVE, AutomationCurve, ac);
+
+#undef GET_HIT_WIDGET
+
+void
+automation_arranger_widget_select_all (
+ AutomationArrangerWidget * self,
+ int select)
+{
+ int i;
+
+ automation_selections_clear (AUTOMATION_SELECTIONS);
+
+ Region * region = CLIP_EDITOR->region;
+
+ /* select everything else */
+ AutomationPoint * ap;
+ for (i = 0; i < region->num_aps; i++)
+ {
+ ap = region->aps[i];
+ automation_point_widget_select (
+ ap->widget, select);
+ }
+
+ /**
+ * Deselect range if deselecting all.
+ */
+ if (!select)
+ {
+ project_set_has_range (0);
+ }
+}
+
+/**
+ * Shows context menu.
+ *
+ * To be called from parent on right click.
+ */
+void
+automation_arranger_widget_show_context_menu (
+ AutomationArrangerWidget * self,
+ gdouble x,
+ gdouble y)
+{
+ GtkWidget *menu, *menuitem;
+
+ /*RegionWidget * clicked_region =*/
+ /*automation_arranger_widget_get_hit_region (*/
+ /*self, x, y);*/
+ /*AutomationPointWidget * clicked_ap =*/
+ /*automation_arranger_widget_get_hit_ap (*/
+ /*self, x, y);*/
+ /*AutomationCurveWidget * ac =*/
+ /*automation_arranger_widget_get_hit_curve (*/
+ /*self, x, y);*/
+
+ menu = gtk_menu_new();
+
+ menuitem = gtk_menu_item_new_with_label("Do something");
+
+ /*g_signal_connect(menuitem, "activate",*/
+ /*(GCallback) view_popup_menu_onDoSomething, treeview);*/
+
+ gtk_menu_shell_append(GTK_MENU_SHELL(menu), menuitem);
+
+ gtk_widget_show_all(menu);
+
+ gtk_menu_popup_at_pointer (GTK_MENU(menu), NULL);
+}
+
+/**
+ * Sets the visibility of the transient and non-
+ * transient objects, lane and non-lane.
+ *
+ * E.g. when moving regions, it hides the original
+ * ones.
+ */
+void
+automation_arranger_widget_update_visibility (
+ AutomationArrangerWidget * self)
+{
+ ARRANGER_SET_OBJ_VISIBILITY_ARRAY (
+ AUTOMATION_SELECTIONS->automation_points,
+ AUTOMATION_SELECTIONS->num_automation_points,
+ AutomationPoint, automation_point);
+}
+
+void
+automation_arranger_widget_on_drag_begin_ap_hit (
+ AutomationArrangerWidget * self,
+ double start_x,
+ AutomationPointWidget * ap_widget)
+{
+ ARRANGER_WIDGET_GET_PRIVATE (self);
+
+ AutomationPoint * ap =
+ ap_widget->automation_point;
+ ar_prv->start_pos_px = start_x;
+ self->start_ap = ap;
+ if (!automation_selections_contains_ap (
+ AUTOMATION_SELECTIONS, ap))
+ {
+ AUTOMATION_SELECTIONS->automation_points[0] =
+ ap;
+ AUTOMATION_SELECTIONS->num_automation_points =
+ 1;
+ }
+
+ self->start_ap = ap;
+
+ /* update arranger action */
+ ar_prv->action =
+ UI_OVERLAY_ACTION_STARTING_MOVING;
+ ui_set_cursor_from_name (GTK_WIDGET (ap_widget),
+ "grabbing");
+
+ /* update selection */
+ if (ar_prv->ctrl_held)
+ {
+ ARRANGER_WIDGET_SELECT_AUTOMATION_POINT (
+ self, ap, F_SELECT, F_APPEND);
+ }
+ else
+ {
+ automation_arranger_widget_select_all (self, 0);
+ ARRANGER_WIDGET_SELECT_AUTOMATION_POINT (
+ self, ap, F_SELECT, F_NO_APPEND);
+ }
+}
+
+/**
+ * Create an AutomationPointat the given Position
+ * in the given Track's AutomationTrack.
+ *
+ * @param pos The pre-snapped position.
+ */
+void
+automation_arranger_widget_create_ap (
+ AutomationArrangerWidget * self,
+ const Position * pos,
+ const double start_y)
+{
+ AutomationTrack * at = CLIP_EDITOR->region->at;
+ g_warn_if_fail (at);
+ ARRANGER_WIDGET_GET_PRIVATE (self);
+
+ float value =
+ automation_track_widget_get_fvalue_at_y (
+ at->widget, start_y);
+
+ ar_prv->action =
+ UI_OVERLAY_ACTION_CREATING_MOVING;
+
+ /* create a new ap */
+ AutomationPoint * ap =
+ automation_point_new_float (
+ value, pos, F_MAIN);
+ self->start_ap = ap;
+
+ /* add it to automation track */
+ automation_region_add_ap (
+ CLIP_EDITOR->region, ap, F_GEN_CURVE_POINTS);
+
+ /* set visibility */
+ arranger_object_info_set_widget_visibility_and_state (
+ &ap->obj_info, 1);
+
+ /* set position to all counterparts */
+ automation_point_set_pos (
+ ap, pos, AO_UPDATE_ALL);
+
+ EVENTS_PUSH (
+ ET_AUTOMATION_POINT_CREATED, ap);
+ ARRANGER_WIDGET_SELECT_AUTOMATION_POINT (
+ self, ap, F_SELECT,
+ F_NO_APPEND);
+}
+
+/**
+ * First determines the selection type (objects/
+ * range), then either finds and selects items or
+ * selects a range.
+ *
+ * @param[in] delete If this is a select-delete
+ * operation
+ */
+void
+automation_arranger_widget_select (
+ AutomationArrangerWidget * self,
+ double offset_x,
+ double offset_y,
+ int delete)
+{
+ int i;
+
+ ARRANGER_WIDGET_GET_PRIVATE (self);
+
+ if (!delete)
+ /* deselect all */
+ arranger_widget_select_all (
+ Z_ARRANGER_WIDGET (self), 0);
+
+#define FIND_ENCLOSED_WIDGETS_OF_TYPE( \
+ caps,cc,sc) \
+ cc * sc; \
+ cc##Widget * sc##_widget; \
+ GtkWidget * sc##_widgets[800]; \
+ int num_##sc##_widgets = 0; \
+ arranger_widget_get_hit_widgets_in_range ( \
+ Z_ARRANGER_WIDGET (self), \
+ caps##_WIDGET_TYPE, \
+ ar_prv->start_x, \
+ ar_prv->start_y, \
+ offset_x, \
+ offset_y, \
+ sc##_widgets, \
+ &num_##sc##_widgets)
+
+ /* find enclosed automation_points */
+ FIND_ENCLOSED_WIDGETS_OF_TYPE (
+ AUTOMATION_POINT, AutomationPoint,
+ automation_point);
+ for (i = 0; i < num_automation_point_widgets; i++)
+ {
+ automation_point_widget =
+ Z_AUTOMATION_POINT_WIDGET (
+ automation_point_widgets[i]);
+
+ automation_point =
+ automation_point_get_main_automation_point (
+ automation_point_widget->automation_point);
+
+ if (delete)
+ automation_region_remove_ap (
+ automation_point->region,
+ automation_point, F_FREE);
+ else
+ ARRANGER_WIDGET_SELECT_AUTOMATION_POINT (
+ self, automation_point, F_SELECT, F_APPEND);
+ }
+
+#undef FIND_ENCLOSED_WIDGETS_OF_TYPE
+}
+
+/**
+ * Moves the AutomationSelections by the given
+ * amount of ticks.
+ *
+ * @param ticks_diff Ticks to move by.
+ * @param copy_moving 1 if copy-moving.
+ */
+void
+automation_arranger_widget_move_items_x (
+ AutomationArrangerWidget * self,
+ long ticks_diff,
+ int copy_moving)
+{
+ automation_selections_add_ticks (
+ AUTOMATION_SELECTIONS, ticks_diff, F_USE_CACHED,
+ copy_moving ?
+ AO_UPDATE_TRANS :
+ AO_UPDATE_ALL);
+
+ /* for arranger refresh */
+ EVENTS_PUSH (ET_AUTOMATION_OBJECTS_IN_TRANSIT,
+ NULL);
+}
+
+/**
+ * Sets width to ruler width and height to
+ * tracklist height.
+ */
+void
+automation_arranger_widget_set_size (
+ AutomationArrangerWidget * self)
+{
+ // set the size
+ /*int ww, hh;*/
+ /*if (self->is_pinned)*/
+ /*gtk_widget_get_size_request (*/
+ /*GTK_WIDGET (MW_PINNED_TRACKLIST),*/
+ /*&ww,*/
+ /*&hh);*/
+ /*else*/
+ /*gtk_widget_get_size_request (*/
+ /*GTK_WIDGET (MW_TRACKLIST),*/
+ /*&ww,*/
+ /*&hh);*/
+ /*RULER_WIDGET_GET_PRIVATE (MW_RULER);*/
+ /*gtk_widget_set_size_request (*/
+ /*GTK_WIDGET (self),*/
+ /*rw_prv->total_px,*/
+ /*hh);*/
+}
+
+/**
+ * To be called once at init time.
+ */
+void
+automation_arranger_widget_setup (
+ AutomationArrangerWidget * self)
+{
+ automation_arranger_widget_set_size (
+ self);
+}
+
+void
+automation_arranger_widget_move_items_y (
+ AutomationArrangerWidget * self,
+ double offset_y)
+{
+ ARRANGER_WIDGET_GET_PRIVATE (self);
+
+ if (AUTOMATION_SELECTIONS->num_automation_points)
+ {
+ AutomationPoint * ap;
+ for (int i = 0;
+ i < AUTOMATION_SELECTIONS->
+ num_automation_points; i++)
+ {
+ ap =
+ AUTOMATION_SELECTIONS->
+ automation_points[i];
+
+ ap =
+ automation_point_get_main_automation_point (ap);
+
+ float fval =
+ automation_track_widget_get_fvalue_at_y (
+ ap->region->at->widget,
+ ar_prv->start_y + offset_y);
+ automation_point_update_fvalue (
+ ap, fval, AO_UPDATE_TRANS);
+ }
+ automation_point_widget_update_tooltip (
+ self->start_ap->widget, 1);
+ }
+}
+
+/**
+ * Returns the ticks objects were moved by since
+ * the start of the drag.
+ *
+ * FIXME not really needed, can use
+ * automation_selections_get_start_pos and the
+ * arranger's earliest_obj_start_pos.
+ */
+static long
+get_moved_diff (
+ AutomationArrangerWidget * self)
+{
+#define GET_DIFF(sc,pos_name) \
+ if (AUTOMATION_SELECTIONS->num_##sc##s) \
+ { \
+ return \
+ position_to_ticks ( \
+ &sc##_get_main_trans_##sc ( \
+ AUTOMATION_SELECTIONS->sc##s[0])->pos_name) - \
+ position_to_ticks ( \
+ &sc##_get_main_##sc ( \
+ AUTOMATION_SELECTIONS->sc##s[0])->pos_name); \
+ }
+
+ GET_DIFF (automation_point, pos);
+
+ g_return_val_if_reached (0);
+}
+
+/**
+ * Sets the default cursor in all selected regions and
+ * intializes start positions.
+ */
+void
+automation_arranger_widget_on_drag_end (
+ AutomationArrangerWidget * self)
+{
+ ARRANGER_WIDGET_GET_PRIVATE (self);
+
+ AutomationPoint * ap;
+ for (int i = 0;
+ i < AUTOMATION_SELECTIONS->
+ num_automation_points; i++)
+ {
+ ap =
+ AUTOMATION_SELECTIONS->automation_points[i];
+ automation_point_widget_update_tooltip (
+ ap->widget, 0);
+ }
+
+ if (ar_prv->action ==
+ UI_OVERLAY_ACTION_RESIZING_L)
+ {
+ }
+ else if (ar_prv->action ==
+ UI_OVERLAY_ACTION_RESIZING_R)
+ {
+ }
+ else if (ar_prv->action ==
+ UI_OVERLAY_ACTION_STARTING_MOVING)
+ {
+ /* if something was clicked with ctrl without
+ * moving*/
+ if (ar_prv->ctrl_held)
+ {
+ /*if (self->start_region &&*/
+ /*self->start_region_was_selected)*/
+ /*{*/
+ /*[> deselect it <]*/
+ /*[>ARRANGER_WIDGET_SELECT_REGION (<]*/
+ /*[>self, self->start_region,<]*/
+ /*[>F_NO_SELECT, F_APPEND);<]*/
+ /*}*/
+ }
+ else if (ar_prv->n_press == 2)
+ {
+ /* double click on object */
+ /*g_message ("DOUBLE CLICK");*/
+ }
+ }
+ else if (ar_prv->action ==
+ UI_OVERLAY_ACTION_MOVING)
+ {
+ /*Position earliest_trans_pos;*/
+ /*automation_selections_get_start_pos (*/
+ /*AUTOMATION_SELECTIONS,*/
+ /*&earliest_trans_pos, 1);*/
+ /*UndoableAction * ua =*/
+ /*(UndoableAction *)*/
+ /*move_automation_selections_action_new (*/
+ /*TL_SELECTIONS,*/
+ /*position_to_ticks (*/
+ /*&earliest_trans_pos) -*/
+ /*position_to_ticks (*/
+ /*&ar_prv->earliest_obj_start_pos),*/
+ /*automation_selections_get_highest_track (*/
+ /*TL_SELECTIONS, F_TRANSIENTS) -*/
+ /*automation_selections_get_highest_track (*/
+ /*TL_SELECTIONS, F_NO_TRANSIENTS));*/
+ /*undo_manager_perform (*/
+ /*UNDO_MANAGER, ua);*/
+ }
+ /* if copy/link-moved */
+ else if (ar_prv->action ==
+ UI_OVERLAY_ACTION_MOVING_COPY ||
+ ar_prv->action ==
+ UI_OVERLAY_ACTION_MOVING_LINK)
+ {
+ /*Position earliest_trans_pos;*/
+ /*automation_selections_get_start_pos (*/
+ /*TL_SELECTIONS,*/
+ /*&earliest_trans_pos, 1);*/
+ /*UndoableAction * ua =*/
+ /*(UndoableAction *)*/
+ /*duplicate_automation_selections_action_new (*/
+ /*TL_SELECTIONS,*/
+ /*position_to_ticks (*/
+ /*&earliest_trans_pos) -*/
+ /*position_to_ticks (*/
+ /*&ar_prv->earliest_obj_start_pos),*/
+ /*automation_selections_get_highest_track (*/
+ /*TL_SELECTIONS, F_TRANSIENTS) -*/
+ /*automation_selections_get_highest_track (*/
+ /*TL_SELECTIONS, F_NO_TRANSIENTS));*/
+ /*automation_selections_reset_transient_poses (*/
+ /*TL_SELECTIONS);*/
+ /*automation_selections_clear (*/
+ /*TL_SELECTIONS);*/
+ /*undo_manager_perform (*/
+ /*UNDO_MANAGER, ua);*/
+ }
+ else if (ar_prv->action ==
+ UI_OVERLAY_ACTION_NONE ||
+ ar_prv->action ==
+ UI_OVERLAY_ACTION_STARTING_SELECTION)
+ {
+ automation_selections_clear (
+ AUTOMATION_SELECTIONS);
+ }
+ /* if something was created */
+ else if (ar_prv->action ==
+ UI_OVERLAY_ACTION_CREATING_MOVING ||
+ ar_prv->action ==
+ UI_OVERLAY_ACTION_CREATING_RESIZING_R)
+ {
+ /*automation_selections_set_to_transient_poses (*/
+ /*TL_SELECTIONS);*/
+ /*automation_selections_set_to_transient_values (*/
+ /*TL_SELECTIONS);*/
+
+ /*UndoableAction * ua =*/
+ /*(UndoableAction *)*/
+ /*create_automation_selections_action_new (*/
+ /*TL_SELECTIONS);*/
+ /*undo_manager_perform (*/
+ /*UNDO_MANAGER, ua);*/
+ }
+ /* if didn't click on something */
+ else
+ {
+ }
+ ar_prv->action = UI_OVERLAY_ACTION_NONE;
+ automation_arranger_widget_update_visibility (
+ self);
+
+ self->start_ap = NULL;
+
+ EVENTS_PUSH (ET_AUTOMATION_SELECTIONS_CHANGED,
+ NULL);
+}
+
+static void
+add_children_from_automation_track (
+ AutomationArrangerWidget * self,
+ AutomationTrack * at)
+{
+ if (!at->track->bot_paned_visible)
+ return;
+
+ int i,j,k;
+ Region * region;
+ AutomationPoint * ap;
+ AutomationCurve * ac;
+ for (i = 0; i < at->num_regions; i++)
+ {
+ region = at->regions[i];
+
+ for (j = 0; j < region->num_aps; j++)
+ {
+ ap = region->aps[j];
+
+ for (k = 0; k < 2; k++)
+ {
+ if (k == 0)
+ ap = automation_point_get_main_automation_point (ap);
+ else if (k == 1)
+ ap = automation_point_get_main_trans_automation_point (ap);
+
+ if (!GTK_IS_WIDGET (ap->widget))
+ ap->widget =
+ automation_point_widget_new (ap);
+
+ gtk_overlay_add_overlay (
+ GTK_OVERLAY (self),
+ GTK_WIDGET (ap->widget));
+ }
+ }
+ for (j = 0; j < region->num_acs; j++)
+ {
+ ac = region->acs[j];
+
+ if (!GTK_IS_WIDGET (ac->widget))
+ ac->widget =
+ automation_curve_widget_new (ac);
+
+ gtk_overlay_add_overlay (
+ GTK_OVERLAY (self),
+ GTK_WIDGET (ac->widget));
+ }
+ }
+}
+
+/**
+ * Refreshes visibility of children.
+ */
+void
+automation_arranger_widget_refresh_visibility (
+ AutomationArrangerWidget * self)
+{
+ GList *children, *iter;
+ children =
+ gtk_container_get_children (
+ GTK_CONTAINER (self));
+ /*GtkWidget * w;*/
+ /*RegionWidget * rw;*/
+ /*Region * region;*/
+ for (iter = children;
+ iter != NULL;
+ iter = g_list_next (iter))
+ {
+ /*w = GTK_WIDGET (iter->data);*/
+
+ /*if (Z_IS_REGION_WIDGET (w))*/
+ /*{*/
+ /*rw = Z_REGION_WIDGET (w);*/
+ /*REGION_WIDGET_GET_PRIVATE (rw);*/
+ /*region = rw_prv->region;*/
+
+ /*arranger_object_info_set_widget_visibility_and_state (*/
+ /*&region->obj_info, 1);*/
+ /*}*/
+ }
+ g_list_free (children);
+}
+
+/**
+ * Readd children.
+ */
+void
+automation_arranger_widget_refresh_children (
+ AutomationArrangerWidget * self)
+{
+ ARRANGER_WIDGET_GET_PRIVATE (self);
+
+ /* remove all children except bg && playhead */
+ GList *children, *iter;
+
+ children =
+ gtk_container_get_children (
+ GTK_CONTAINER (self));
+ for (iter = children;
+ iter != NULL;
+ iter = g_list_next (iter))
+ {
+ GtkWidget * widget = GTK_WIDGET (iter->data);
+ if (widget != (GtkWidget *) ar_prv->bg &&
+ widget != (GtkWidget *) ar_prv->playhead)
+ {
+ /*g_object_ref (widget);*/
+ gtk_container_remove (
+ GTK_CONTAINER (self),
+ widget);
+ }
+ }
+ g_list_free (children);
+
+ /* add tracks */
+ AutomationTrack * at = CLIP_EDITOR->region->at;
+ add_children_from_automation_track (
+ self, at);
+
+ automation_arranger_widget_refresh_visibility (
+ self);
+
+ gtk_overlay_reorder_overlay (
+ GTK_OVERLAY (self),
+ (GtkWidget *) ar_prv->playhead, -1);
+}
+
+/**
+ * Scroll to the given position.
+ */
+void
+automation_arranger_widget_scroll_to (
+ AutomationArrangerWidget * self,
+ Position * pos)
+{
+ /* TODO */
+
+}
+
+static gboolean
+on_focus (GtkWidget *widget,
+ gpointer user_data)
+{
+ /*g_message ("automation focused");*/
+ MAIN_WINDOW->last_focused = widget;
+
+ return FALSE;
+}
+
+static void
+automation_arranger_widget_class_init (
+ AutomationArrangerWidgetClass * klass)
+{
+}
+
+static void
+automation_arranger_widget_init (
+ AutomationArrangerWidget *self )
+{
+ g_signal_connect (
+ self, "grab-focus",
+ G_CALLBACK (on_focus), self);
+}
diff --git a/src/gui/widgets/automation_arranger_bg.c b/src/gui/widgets/automation_arranger_bg.c
new file mode 100644
index 0000000..94202cd
--- /dev/null
+++ b/src/gui/widgets/automation_arranger_bg.c
@@ -0,0 +1,82 @@
+/*
+ * Copyright (C) 2019 Alexandros Theodotou <alex at zrythm dot org>
+ *
+ * This file is part of Zrythm
+ *
+ * Zrythm is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Zrythm 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 Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with Zrythm. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+#include "zrythm.h"
+#include "project.h"
+#include "settings/settings.h"
+#include "audio/transport.h"
+#include "gui/widgets/arranger.h"
+#include "gui/widgets/bot_dock_edge.h"
+#include "gui/widgets/center_dock.h"
+#include "gui/widgets/clip_editor.h"
+#include "gui/widgets/main_window.h"
+#include "gui/widgets/automation_arranger.h"
+#include "gui/widgets/automation_arranger_bg.h"
+#include "gui/widgets/ruler.h"
+#include "gui/widgets/piano_roll.h"
+#include "gui/widgets/ruler.h"
+#include "gui/widgets/tracklist.h"
+
+#include <gtk/gtk.h>
+
+G_DEFINE_TYPE (AutomationArrangerBgWidget,
+ automation_arranger_bg_widget,
+ ARRANGER_BG_WIDGET_TYPE)
+
+static gboolean
+automation_arranger_draw_cb (
+ GtkWidget *widget,
+ cairo_t *cr,
+ gpointer data)
+{
+
+ return FALSE;
+}
+
+AutomationArrangerBgWidget *
+automation_arranger_bg_widget_new (
+ RulerWidget * ruler,
+ ArrangerWidget * arranger)
+{
+ AutomationArrangerBgWidget * self =
+ g_object_new (AUTOMATION_ARRANGER_BG_WIDGET_TYPE,
+ NULL);
+
+ ARRANGER_BG_WIDGET_GET_PRIVATE (self);
+ ab_prv->ruler = ruler;
+ ab_prv->arranger = arranger;
+
+ g_signal_connect (
+ G_OBJECT (self), "draw",
+ G_CALLBACK (automation_arranger_draw_cb), NULL);
+
+ return self;
+}
+
+static void
+automation_arranger_bg_widget_class_init (
+ AutomationArrangerBgWidgetClass * _klass)
+{
+}
+
+static void
+automation_arranger_bg_widget_init (
+ AutomationArrangerBgWidget *self )
+{
+}
diff --git a/src/gui/widgets/automation_curve.c b/src/gui/widgets/automation_curve.c
index 081fd01..3b5ae36 100644
--- a/src/gui/widgets/automation_curve.c
+++ b/src/gui/widgets/automation_curve.c
@@ -21,6 +21,7 @@
#include <math.h>
+#include "audio/automation_region.h"
#include "audio/automation_track.h"
#include "audio/bus_track.h"
#include "audio/channel.h"
@@ -74,7 +75,7 @@ drag_update (GtkGestureDrag * gesture,
int use_y = 1;
/*double multiplier = 0.005;*/
double diff = use_y ? offset_y - self->last_y : offset_x - self->last_x;
- double height = gtk_widget_get_allocated_height (GTK_WIDGET (self));
+ /*double height = gtk_widget_get_allocated_height (GTK_WIDGET (self));*/
double adjusted_diff = diff / 120.0;
double new_curve_val = clamp (curve_val_from_real (self) + adjusted_diff,
1.0,
@@ -133,8 +134,7 @@ automation_curve_draw_cb (
/*cairo_fill (self->cached_cr);*/
GdkRGBA * color;
- Track * track = self->ac->at->track;
- /*ChannelTrack * ct = (ChannelTrack *) track;*/
+ Track * track = self->ac->region->at->track;
color = &track->color;
/*if (self->hover)*/
/*{*/
@@ -157,10 +157,12 @@ automation_curve_draw_cb (
cairo_set_source_rgba (self->cached_cr, color->red, color->green, color->blue, 0.7);
/*}*/
- AutomationPoint * next_ap = automation_track_get_ap_after_curve (self->ac->at,
- self->ac);
- AutomationPoint * prev_ap = automation_track_get_ap_before_curve (self->ac->at,
- self->ac);
+ AutomationPoint * next_ap =
+ automation_region_get_ap_after_curve (
+ self->ac->region, self->ac);
+ AutomationPoint * prev_ap =
+ automation_region_get_ap_before_curve (
+ self->ac->region, self->ac);
/*gtk_widget_translate_coordinates(*/
/*GTK_WIDGET (ap->widget),*/
diff --git a/src/gui/widgets/automation_point.c b/src/gui/widgets/automation_point.c
index cc05c8f..0f22ce0 100644
--- a/src/gui/widgets/automation_point.c
+++ b/src/gui/widgets/automation_point.c
@@ -53,7 +53,7 @@ draw_cb (
context, cr, 0, 0, width, height);
Track * track =
- self->automation_point->at->track;
+ self->automation_point->region->at->track;
GdkRGBA * color = &track->color;
cairo_set_source_rgba (
cr, color->red, color->green, color->blue, 0.7);
@@ -105,7 +105,7 @@ on_motion (GtkWidget * widget,
DEFINE_ARRANGER_OBJECT_WIDGET_SELECT (
AutomationPoint, automation_point,
- timeline_selections, TL_SELECTIONS);
+ automation_selections, AUTOMATION_SELECTIONS);
void
automation_point_widget_update_tooltip (
@@ -119,7 +119,7 @@ automation_point_widget_update_tooltip (
char * tooltip =
g_strdup_printf (
"%s %f",
- ap->at->automatable->label,
+ ap->region->at->automatable->label,
ap->fvalue);
gtk_widget_set_tooltip_text (
GTK_WIDGET (self), tooltip);
diff --git a/src/gui/widgets/automation_region.c b/src/gui/widgets/automation_region.c
new file mode 100644
index 0000000..57a8009
--- /dev/null
+++ b/src/gui/widgets/automation_region.c
@@ -0,0 +1,84 @@
+/*
+ * Copyright (C) 2018-2019 Alexandros Theodotou <alex at zrythm dot org>
+ *
+ * This file is part of Zrythm
+ *
+ * Zrythm is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Zrythm 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 Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with Zrythm. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+#include "audio/bus_track.h"
+#include "audio/channel.h"
+#include "audio/instrument_track.h"
+#include "audio/midi_note.h"
+#include "audio/track.h"
+#include "gui/widgets/arranger.h"
+#include "gui/widgets/center_dock.h"
+#include "gui/widgets/main_window.h"
+#include "gui/widgets/midi_arranger.h"
+#include "gui/widgets/automation_region.h"
+#include "gui/widgets/region.h"
+#include "gui/widgets/ruler.h"
+#include "gui/widgets/timeline_arranger.h"
+#include "utils/cairo.h"
+
+G_DEFINE_TYPE (AutomationRegionWidget,
+ automation_region_widget,
+ REGION_WIDGET_TYPE)
+
+
+#define Y_PADDING 6.f
+#define Y_HALF_PADDING 3.f
+
+static gboolean
+automation_region_draw_cb (
+ GtkWidget * widget,
+ cairo_t *cr,
+ AutomationRegionWidget * self)
+{
+
+ return FALSE;
+}
+
+AutomationRegionWidget *
+automation_region_widget_new (
+ Region * region)
+{
+ AutomationRegionWidget * self =
+ g_object_new (
+ AUTOMATION_REGION_WIDGET_TYPE,
+ NULL);
+
+ region_widget_setup (
+ Z_REGION_WIDGET (self), region);
+ REGION_WIDGET_GET_PRIVATE (self);
+
+ /* connect signals */
+ g_signal_connect (
+ G_OBJECT (rw_prv->drawing_area), "draw",
+ G_CALLBACK (automation_region_draw_cb), self);
+
+ return self;
+}
+
+static void
+automation_region_widget_class_init (
+ AutomationRegionWidgetClass * klass)
+{
+}
+
+static void
+automation_region_widget_init (
+ AutomationRegionWidget * self)
+{
+}
diff --git a/src/gui/widgets/chord_arranger.c b/src/gui/widgets/chord_arranger.c
new file mode 100644
index 0000000..4a1d98e
--- /dev/null
+++ b/src/gui/widgets/chord_arranger.c
@@ -0,0 +1,835 @@
+/*
+ * Copyright (C) 2018-2019 Alexandros Theodotou <alex at zrythm dot org>
+ *
+ * This file is part of Zrythm
+ *
+ * Zrythm is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Zrythm 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 Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with Zrythm. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+/**
+ * \file
+ *
+ * The chord containing regions and other
+ * objects.
+ */
+
+#include "actions/undoable_action.h"
+#include "actions/create_chord_selections_action.h"
+#include "actions/undo_manager.h"
+#include "actions/duplicate_chord_selections_action.h"
+#include "actions/move_chord_selections_action.h"
+#include "audio/automation_track.h"
+#include "audio/automation_tracklist.h"
+#include "audio/audio_track.h"
+#include "audio/bus_track.h"
+#include "audio/channel.h"
+#include "audio/chord_object.h"
+#include "audio/chord_region.h"
+#include "audio/chord_track.h"
+#include "audio/instrument_track.h"
+#include "audio/marker_track.h"
+#include "audio/master_track.h"
+#include "audio/midi_region.h"
+#include "audio/mixer.h"
+#include "audio/scale_object.h"
+#include "audio/track.h"
+#include "audio/tracklist.h"
+#include "audio/transport.h"
+#include "gui/widgets/arranger.h"
+#include "gui/widgets/automation_curve.h"
+#include "gui/widgets/automation_track.h"
+#include "gui/widgets/automation_point.h"
+#include "gui/widgets/bot_dock_edge.h"
+#include "gui/widgets/center_dock.h"
+#include "gui/widgets/chord_object.h"
+#include "gui/widgets/color_area.h"
+#include "gui/widgets/inspector.h"
+#include "gui/widgets/main_window.h"
+#include "gui/widgets/marker.h"
+#include "gui/widgets/midi_arranger.h"
+#include "gui/widgets/midi_arranger_bg.h"
+#include "gui/widgets/midi_region.h"
+#include "gui/widgets/piano_roll.h"
+#include "gui/widgets/pinned_tracklist.h"
+#include "gui/widgets/midi_note.h"
+#include "gui/widgets/region.h"
+#include "gui/widgets/scale_object.h"
+#include "gui/widgets/ruler.h"
+#include "gui/widgets/chord_arranger.h"
+#include "gui/widgets/chord_arranger_bg.h"
+#include "gui/widgets/track.h"
+#include "gui/widgets/tracklist.h"
+#include "project.h"
+#include "settings/settings.h"
+#include "utils/arrays.h"
+#include "utils/cairo.h"
+#include "utils/flags.h"
+#include "utils/objects.h"
+#include "utils/ui.h"
+#include "zrythm.h"
+
+#include <gtk/gtk.h>
+
+G_DEFINE_TYPE (ChordArrangerWidget,
+ chord_arranger_widget,
+ ARRANGER_WIDGET_TYPE)
+
+/**
+ * To be called from get_child_position in parent widget.
+ *
+ * Used to allocate the overlay children.
+ */
+void
+chord_arranger_widget_set_allocation (
+ ChordArrangerWidget * self,
+ GtkWidget * widget,
+ GdkRectangle * allocation)
+{
+ if (Z_IS_CHORD_OBJECT_WIDGET (widget))
+ {
+ ChordObjectWidget * cw =
+ Z_CHORD_OBJECT_WIDGET (widget);
+ ChordObject * co =
+ cw->chord_object;
+ Track * track = P_CHORD_TRACK;
+
+ gint wx, wy;
+ gtk_widget_translate_coordinates (
+ GTK_WIDGET (track->widget),
+ GTK_WIDGET (self),
+ 0, 0, &wx, &wy);
+
+ allocation->x =
+ ui_pos_to_px_chord_editor (
+ &co->pos, 1);
+ char * chord_str =
+ chord_descriptor_to_string (co->descr);
+ int textw, texth;
+ z_cairo_get_text_extents_for_widget (
+ widget, chord_str, &textw, &texth);
+ g_free (chord_str);
+ allocation->width =
+ textw + CHORD_OBJECT_WIDGET_TRIANGLE_W +
+ Z_CAIRO_TEXT_PADDING * 2;
+
+ int track_height =
+ gtk_widget_get_allocated_height (
+ GTK_WIDGET (track->widget));
+ int obj_height =
+ texth + Z_CAIRO_TEXT_PADDING * 2;
+ allocation->y =
+ ((wy + track_height) - obj_height) -
+ track_height / 2;
+ allocation->height = obj_height;
+ }
+}
+
+/**
+ * Returns the appropriate cursor based on the
+ * current hover_x and y.
+ */
+ArrangerCursor
+chord_arranger_widget_get_cursor (
+ ChordArrangerWidget * self,
+ UiOverlayAction action,
+ Tool tool)
+{
+ ArrangerCursor ac = ARRANGER_CURSOR_SELECT;
+
+ ARRANGER_WIDGET_GET_PRIVATE (self);
+
+ ChordObjectWidget * cw =
+ chord_arranger_widget_get_hit_chord (
+ self,
+ ar_prv->hover_x,
+ ar_prv->hover_y);
+
+ int is_hit = cw != NULL;
+
+ switch (action)
+ {
+ case UI_OVERLAY_ACTION_NONE:
+ switch (P_TOOL)
+ {
+ case TOOL_SELECT_NORMAL:
+ {
+ if (is_hit)
+ {
+ return ARRANGER_CURSOR_GRAB;
+ }
+ else
+ {
+ /* set cursor to normal */
+ return ARRANGER_CURSOR_SELECT;
+ }
+ }
+ break;
+ case TOOL_SELECT_STRETCH:
+ break;
+ case TOOL_EDIT:
+ ac = ARRANGER_CURSOR_EDIT;
+ break;
+ case TOOL_CUT:
+ ac = ARRANGER_CURSOR_CUT;
+ break;
+ case TOOL_ERASER:
+ ac = ARRANGER_CURSOR_ERASER;
+ break;
+ case TOOL_RAMP:
+ ac = ARRANGER_CURSOR_RAMP;
+ break;
+ case TOOL_AUDITION:
+ ac = ARRANGER_CURSOR_AUDITION;
+ break;
+ }
+ break;
+ case UI_OVERLAY_ACTION_STARTING_DELETE_SELECTION:
+ case UI_OVERLAY_ACTION_DELETE_SELECTING:
+ case UI_OVERLAY_ACTION_ERASING:
+ ac = ARRANGER_CURSOR_ERASER;
+ break;
+ case UI_OVERLAY_ACTION_STARTING_MOVING_COPY:
+ case UI_OVERLAY_ACTION_MOVING_COPY:
+ ac = ARRANGER_CURSOR_GRABBING_COPY;
+ break;
+ case UI_OVERLAY_ACTION_STARTING_MOVING:
+ case UI_OVERLAY_ACTION_MOVING:
+ ac = ARRANGER_CURSOR_GRABBING;
+ break;
+ case UI_OVERLAY_ACTION_STARTING_MOVING_LINK:
+ case UI_OVERLAY_ACTION_MOVING_LINK:
+ ac = ARRANGER_CURSOR_GRABBING_LINK;
+ break;
+ case UI_OVERLAY_ACTION_RESIZING_L:
+ ac = ARRANGER_CURSOR_RESIZING_L;
+ break;
+ case UI_OVERLAY_ACTION_RESIZING_R:
+ ac = ARRANGER_CURSOR_RESIZING_R;
+ break;
+ default:
+ ac = ARRANGER_CURSOR_SELECT;
+ break;
+ }
+
+ return ac;
+}
+
+#define GET_HIT_WIDGET(caps,cc,sc) \
+cc##Widget * \
+chord_arranger_widget_get_hit_##sc ( \
+ ChordArrangerWidget * self, \
+ double x, \
+ double y) \
+{ \
+ GtkWidget * widget = \
+ ui_get_hit_child ( \
+ GTK_CONTAINER (self), x, y, \
+ caps##_WIDGET_TYPE); \
+ if (widget) \
+ { \
+ return Z_##caps##_WIDGET (widget); \
+ } \
+ return NULL; \
+}
+
+GET_HIT_WIDGET (
+ CHORD_OBJECT, ChordObject, chord);
+
+#undef GET_HIT_WIDGET
+
+void
+chord_arranger_widget_select_all (
+ ChordArrangerWidget * self,
+ int select)
+{
+ chord_selections_clear (CHORD_SELECTIONS);
+
+ /* select everything else */
+ Region * r = CLIP_EDITOR->region;
+ ChordObject * chord;
+ for (int i = 0; i < r->num_chord_objects; i++)
+ {
+ chord = r->chord_objects[i];
+ chord_object_widget_select (
+ chord->widget, select);
+ }
+}
+
+/**
+ * Shows context menu.
+ *
+ * To be called from parent on right click.
+ */
+void
+chord_arranger_widget_show_context_menu (
+ ChordArrangerWidget * self,
+ gdouble x,
+ gdouble y)
+{
+ GtkWidget *menu, *menuitem;
+
+ /*RegionWidget * clicked_region =*/
+ /*chord_arranger_widget_get_hit_region (*/
+ /*self, x, y);*/
+ /*ChordWidget * clicked_chord =*/
+ /*chord_arranger_widget_get_hit_chord (*/
+ /*self, x, y);*/
+ /*AutomationPointWidget * clicked_ap =*/
+ /*chord_arranger_widget_get_hit_ap (*/
+ /*self, x, y);*/
+ /*AutomationCurveWidget * ac =*/
+ /*chord_arranger_widget_get_hit_curve (*/
+ /*self, x, y);*/
+
+ menu = gtk_menu_new();
+
+ menuitem = gtk_menu_item_new_with_label("Do something");
+
+ /*g_signal_connect(menuitem, "activate",*/
+ /*(GCallback) view_popup_menu_onDoSomething, treeview);*/
+
+ gtk_menu_shell_append(GTK_MENU_SHELL(menu), menuitem);
+
+ gtk_widget_show_all(menu);
+
+ gtk_menu_popup_at_pointer (GTK_MENU(menu), NULL);
+}
+
+/**
+ * Sets the visibility of the transient and non-
+ * transient objects, lane and non-lane.
+ *
+ * E.g. when moving regions, it hides the original
+ * ones.
+ */
+void
+chord_arranger_widget_update_visibility (
+ ChordArrangerWidget * self)
+{
+ ARRANGER_SET_OBJ_VISIBILITY_ARRAY (
+ CHORD_SELECTIONS->chord_objects,
+ CHORD_SELECTIONS->num_chord_objects,
+ ChordObject, chord_object);
+}
+
+void
+chord_arranger_widget_on_drag_begin_chord_hit (
+ ChordArrangerWidget * self,
+ double start_x,
+ ChordObjectWidget * cw)
+{
+ ARRANGER_WIDGET_GET_PRIVATE (self);
+
+ ChordObject * chord = cw->chord_object;
+ self->start_chord_object = chord;
+
+ /* update arranger action */
+ ar_prv->action =
+ UI_OVERLAY_ACTION_STARTING_MOVING;
+ /* FIXME cursor should be set automatically */
+ ui_set_cursor_from_name (
+ GTK_WIDGET (cw), "grabbing");
+
+ int selected = chord_object_is_selected (chord);
+
+ /* select chord if unselected */
+ if (P_TOOL == TOOL_SELECT_NORMAL ||
+ P_TOOL == TOOL_SELECT_STRETCH ||
+ P_TOOL == TOOL_EDIT)
+ {
+ /* if ctrl held & not selected, add to
+ * selections */
+ if (ar_prv->ctrl_held && !selected)
+ {
+ ARRANGER_WIDGET_SELECT_CHORD (
+ self, chord, F_SELECT, F_APPEND);
+ }
+ /* if ctrl not held & not selected, make it
+ * the only selection */
+ else if (!ar_prv->ctrl_held &&
+ !selected)
+ {
+ ARRANGER_WIDGET_SELECT_CHORD (
+ self, chord, F_SELECT, F_NO_APPEND);
+ }
+ }
+}
+
+/**
+ * Create a ChordObject at the given Position in the
+ * given Track.
+ *
+ * @param pos The pre-snapped position.
+ */
+void
+chord_arranger_widget_create_chord (
+ ChordArrangerWidget * self,
+ const Position * pos)
+{
+ ARRANGER_WIDGET_GET_PRIVATE (self);
+
+ ar_prv->action =
+ UI_OVERLAY_ACTION_CREATING_MOVING;
+
+ /* create a new chord */
+ ChordDescriptor * descr =
+ chord_descriptor_new (
+ NOTE_B, 1, NOTE_B, CHORD_TYPE_MIN,
+ CHORD_ACC_7, 0);
+ ChordObject * chord =
+ chord_object_new (
+ descr, 1);
+
+ /* add it to chord region */
+ chord_region_add_chord_object (
+ CLIP_EDITOR->region, chord);
+
+ /* set visibility */
+ arranger_object_info_set_widget_visibility_and_state (
+ &chord->obj_info, 1);
+
+ chord_object_set_pos (
+ chord, pos, AO_UPDATE_ALL);
+
+ EVENTS_PUSH (ET_CHORD_OBJECT_CREATED, chord);
+ ARRANGER_WIDGET_SELECT_CHORD (
+ self, chord, F_SELECT,
+ F_NO_APPEND);
+}
+
+/**
+ * Finds and selects items.
+ *
+ * @param[in] delete If this is a select-delete
+ * operation
+ */
+void
+chord_arranger_widget_select (
+ ChordArrangerWidget * self,
+ double offset_x,
+ double offset_y,
+ int delete)
+{
+ int i;
+
+ ARRANGER_WIDGET_GET_PRIVATE (self);
+
+ if (!delete)
+ /* deselect all */
+ arranger_widget_select_all (
+ Z_ARRANGER_WIDGET (self), 0);
+
+#define FIND_ENCLOSED_WIDGETS_OF_TYPE( \
+ caps,cc,sc) \
+ cc * sc; \
+ cc##Widget * sc##_widget; \
+ GtkWidget * sc##_widgets[800]; \
+ int num_##sc##_widgets = 0; \
+ arranger_widget_get_hit_widgets_in_range ( \
+ Z_ARRANGER_WIDGET (self), \
+ caps##_WIDGET_TYPE, \
+ ar_prv->start_x, \
+ ar_prv->start_y, \
+ offset_x, \
+ offset_y, \
+ sc##_widgets, \
+ &num_##sc##_widgets)
+
+ FIND_ENCLOSED_WIDGETS_OF_TYPE (
+ CHORD_OBJECT, ChordObject, chord_object);
+ for (i = 0; i < num_chord_object_widgets; i++)
+ {
+ chord_object_widget =
+ Z_CHORD_OBJECT_WIDGET (
+ chord_object_widgets[i]);
+
+ chord_object =
+ chord_object_get_main_chord_object (
+ chord_object_widget->chord_object);
+
+ if (delete)
+ chord_region_remove_chord_object (
+ chord_object->region,
+ chord_object, F_FREE);
+ else
+ ARRANGER_WIDGET_SELECT_CHORD (
+ self, chord_object, F_SELECT, F_APPEND);
+ }
+
+#undef FIND_ENCLOSED_WIDGETS_OF_TYPE
+}
+
+/**
+ * Moves the ChordSelections by the given
+ * amount of ticks.
+ *
+ * @param ticks_diff Ticks to move by.
+ * @param copy_moving 1 if copy-moving.
+ */
+void
+chord_arranger_widget_move_items_x (
+ ChordArrangerWidget * self,
+ long ticks_diff,
+ int copy_moving)
+{
+ chord_selections_add_ticks (
+ CHORD_SELECTIONS, ticks_diff, F_USE_CACHED,
+ copy_moving ?
+ AO_UPDATE_TRANS :
+ AO_UPDATE_ALL);
+
+ /* for arranger refresh */
+ EVENTS_PUSH (ET_CHORD_OBJECTS_IN_TRANSIT,
+ NULL);
+}
+
+/**
+ * Sets width to ruler width and height to
+ * tracklist height.
+ */
+void
+chord_arranger_widget_set_size (
+ ChordArrangerWidget * self)
+{
+ // set the size
+ /*int ww, hh;*/
+ /*if (self->is_pinned)*/
+ /*gtk_widget_get_size_request (*/
+ /*GTK_WIDGET (MW_PINNED_TRACKLIST),*/
+ /*&ww,*/
+ /*&hh);*/
+ /*else*/
+ /*gtk_widget_get_size_request (*/
+ /*GTK_WIDGET (MW_TRACKLIST),*/
+ /*&ww,*/
+ /*&hh);*/
+ /*RULER_WIDGET_GET_PRIVATE (MW_RULER);*/
+ /*gtk_widget_set_size_request (*/
+ /*GTK_WIDGET (self),*/
+ /*rw_prv->total_px,*/
+ /*hh);*/
+}
+
+/**
+ * To be called once at init time.
+ */
+void
+chord_arranger_widget_setup (
+ ChordArrangerWidget * self)
+{
+ chord_arranger_widget_set_size (
+ self);
+}
+
+void
+chord_arranger_widget_move_items_y (
+ ChordArrangerWidget * self,
+ double offset_y)
+{
+}
+
+/**
+ * Returns the ticks objects were moved by since
+ * the start of the drag.
+ *
+ * FIXME not really needed, can use
+ * chord_selections_get_start_pos and the
+ * arranger's earliest_obj_start_pos.
+ */
+static long
+get_moved_diff (
+ ChordArrangerWidget * self)
+{
+#define GET_DIFF(sc,pos_name) \
+ if (CHORD_SELECTIONS->num_##sc##s) \
+ { \
+ return \
+ position_to_ticks ( \
+ &sc##_get_main_trans_##sc ( \
+ CHORD_SELECTIONS->sc##s[0])->pos_name) - \
+ position_to_ticks ( \
+ &sc##_get_main_##sc ( \
+ CHORD_SELECTIONS->sc##s[0])->pos_name); \
+ }
+
+ GET_DIFF (chord_object, pos);
+
+ g_return_val_if_reached (0);
+}
+
+/**
+ * Sets the default cursor in all selected regions and
+ * intializes start positions.
+ */
+void
+chord_arranger_widget_on_drag_end (
+ ChordArrangerWidget * self)
+{
+ ARRANGER_WIDGET_GET_PRIVATE (self);
+
+ switch (ar_prv->action)
+ {
+ case UI_OVERLAY_ACTION_STARTING_MOVING:
+ {
+ /* if something was clicked with ctrl without
+ * moving*/
+ if (ar_prv->ctrl_held)
+ {
+ /*if (self->start_region &&*/
+ /*self->start_region_was_selected)*/
+ /*{*/
+ /*[> deselect it <]*/
+ /*ARRANGER_WIDGET_SELECT_REGION (*/
+ /*self, self->start_region,*/
+ /*F_NO_SELECT, F_APPEND);*/
+ /*}*/
+ }
+ else if (ar_prv->n_press == 2)
+ {
+ /* double click on object */
+ /*g_message ("DOUBLE CLICK");*/
+ }
+ }
+ break;
+ case UI_OVERLAY_ACTION_MOVING:
+ {
+ Position earliest_trans_pos;
+ chord_selections_get_start_pos (
+ CHORD_SELECTIONS,
+ &earliest_trans_pos, F_TRANSIENTS, 0);
+ /*UndoableAction * ua =*/
+ /*(UndoableAction *)*/
+ /*move_chord_selections_action_new (*/
+ /*TL_SELECTIONS,*/
+ /*position_to_ticks (*/
+ /*&earliest_trans_pos) -*/
+ /*position_to_ticks (*/
+ /*&ar_prv->earliest_obj_start_pos),*/
+ /*chord_selections_get_highest_track (*/
+ /*TL_SELECTIONS, F_TRANSIENTS) -*/
+ /*chord_selections_get_highest_track (*/
+ /*TL_SELECTIONS, F_NO_TRANSIENTS));*/
+ /*undo_manager_perform (*/
+ /*UNDO_MANAGER, ua);*/
+ }
+ break;
+ case UI_OVERLAY_ACTION_MOVING_COPY:
+ case UI_OVERLAY_ACTION_MOVING_LINK:
+ {
+ Position earliest_trans_pos;
+ chord_selections_get_start_pos (
+ CHORD_SELECTIONS,
+ &earliest_trans_pos, F_TRANSIENTS, 0);
+ /*UndoableAction * ua =*/
+ /*(UndoableAction *)*/
+ /*duplicate_chord_selections_action_new (*/
+ /*TL_SELECTIONS,*/
+ /*position_to_ticks (*/
+ /*&earliest_trans_pos) -*/
+ /*position_to_ticks (*/
+ /*&ar_prv->earliest_obj_start_pos),*/
+ /*chord_selections_get_highest_track (*/
+ /*TL_SELECTIONS, F_TRANSIENTS) -*/
+ /*chord_selections_get_highest_track (*/
+ /*TL_SELECTIONS, F_NO_TRANSIENTS));*/
+ /*chord_selections_reset_transient_poses (*/
+ /*TL_SELECTIONS);*/
+ /*chord_selections_clear (*/
+ /*TL_SELECTIONS);*/
+ /*undo_manager_perform (*/
+ /*UNDO_MANAGER, ua);*/
+ }
+ break;
+ case UI_OVERLAY_ACTION_NONE:
+ case UI_OVERLAY_ACTION_STARTING_SELECTION:
+ {
+ chord_selections_clear (
+ CHORD_SELECTIONS);
+ }
+ break;
+ case UI_OVERLAY_ACTION_CREATING_MOVING:
+ {
+ /*chord_selections_set_to_transient_poses (*/
+ /*CHORD_SELECTIONS);*/
+ /*chord_selections_set_to_transient_values (*/
+ /*CHORD_SELECTIONS);*/
+
+ /*UndoableAction * ua =*/
+ /*(UndoableAction *)*/
+ /*create_chord_selections_action_new (*/
+ /*TL_SELECTIONS);*/
+ /*undo_manager_perform (*/
+ /*UNDO_MANAGER, ua);*/
+ }
+ break;
+ /* if didn't click on something */
+ default:
+ {
+ }
+ break;
+ }
+ ar_prv->action = UI_OVERLAY_ACTION_NONE;
+ chord_arranger_widget_update_visibility (self);
+
+ EVENTS_PUSH (ET_CHORD_SELECTIONS_CHANGED, NULL);
+}
+
+static void
+add_children_from_chord_track (
+ ChordArrangerWidget * self,
+ ChordTrack * ct)
+{
+ int i, j, k;
+ Region * r;
+ ChordObject * c;
+ for (i = 0; i < ct->num_chord_regions; i++)
+ {
+ r = ct->chord_regions[j];
+
+ for (j = 0; j < r->num_chord_objects; j++)
+ {
+ c = r->chord_objects[j];
+
+ for (k = 0 ; k < 2; k++)
+ {
+ if (k == 0)
+ c =
+ chord_object_get_main_chord_object (c);
+ else if (k == 1)
+ c =
+ chord_object_get_main_trans_chord_object (c);
+
+ if (!c->widget)
+ c->widget =
+ chord_object_widget_new (c);
+
+ gtk_overlay_add_overlay (
+ GTK_OVERLAY (self),
+ GTK_WIDGET (c->widget));
+ }
+ }
+ }
+}
+
+/**
+ * Refreshes visibility of children.
+ */
+void
+chord_arranger_widget_refresh_visibility (
+ ChordArrangerWidget * self)
+{
+ GList *children, *iter;
+ children =
+ gtk_container_get_children (
+ GTK_CONTAINER (self));
+ /*GtkWidget * w;*/
+ /*RegionWidget * rw;*/
+ /*Region * region;*/
+ for (iter = children;
+ iter != NULL;
+ iter = g_list_next (iter))
+ {
+ /*w = GTK_WIDGET (iter->data);*/
+
+ /*if (Z_IS_REGION_WIDGET (w))*/
+ /*{*/
+ /*rw = Z_REGION_WIDGET (w);*/
+ /*REGION_WIDGET_GET_PRIVATE (rw);*/
+ /*region = rw_prv->region;*/
+
+ /*arranger_object_info_set_widget_visibility_and_state (*/
+ /*&region->obj_info, 1);*/
+ /*}*/
+ }
+ g_list_free (children);
+}
+
+/**
+ * Readd children.
+ */
+void
+chord_arranger_widget_refresh_children (
+ ChordArrangerWidget * self)
+{
+ ARRANGER_WIDGET_GET_PRIVATE (self);
+
+ /* remove all children except bg && playhead */
+ GList *children, *iter;
+
+ children =
+ gtk_container_get_children (
+ GTK_CONTAINER (self));
+ for (iter = children;
+ iter != NULL;
+ iter = g_list_next (iter))
+ {
+ GtkWidget * widget = GTK_WIDGET (iter->data);
+ if (widget != (GtkWidget *) ar_prv->bg &&
+ widget != (GtkWidget *) ar_prv->playhead)
+ {
+ /*g_object_ref (widget);*/
+ gtk_container_remove (
+ GTK_CONTAINER (self),
+ widget);
+ }
+ }
+ g_list_free (children);
+
+ add_children_from_chord_track (
+ self, P_CHORD_TRACK);
+
+ chord_arranger_widget_update_visibility (self);
+
+ gtk_overlay_reorder_overlay (
+ GTK_OVERLAY (self),
+ (GtkWidget *) ar_prv->playhead, -1);
+}
+
+/**
+ * Scroll to the given position.
+ */
+void
+chord_arranger_widget_scroll_to (
+ ChordArrangerWidget * self,
+ Position * pos)
+{
+ /* TODO */
+
+}
+
+static gboolean
+on_focus (
+ GtkWidget * widget,
+ gpointer user_data)
+{
+ /*g_message ("chord focused");*/
+ MAIN_WINDOW->last_focused = widget;
+
+ return FALSE;
+}
+
+static void
+chord_arranger_widget_class_init (
+ ChordArrangerWidgetClass * klass)
+{
+}
+
+static void
+chord_arranger_widget_init (
+ ChordArrangerWidget *self )
+{
+ g_signal_connect (
+ self, "grab-focus",
+ G_CALLBACK (on_focus), self);
+}
diff --git a/src/gui/widgets/chord_arranger_bg.c b/src/gui/widgets/chord_arranger_bg.c
new file mode 100644
index 0000000..fd93347
--- /dev/null
+++ b/src/gui/widgets/chord_arranger_bg.c
@@ -0,0 +1,82 @@
+/*
+ * Copyright (C) 2019 Alexandros Theodotou <alex at zrythm dot org>
+ *
+ * This file is part of Zrythm
+ *
+ * Zrythm is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Zrythm 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 Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with Zrythm. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+#include "zrythm.h"
+#include "project.h"
+#include "settings/settings.h"
+#include "audio/transport.h"
+#include "gui/widgets/arranger.h"
+#include "gui/widgets/bot_dock_edge.h"
+#include "gui/widgets/center_dock.h"
+#include "gui/widgets/clip_editor.h"
+#include "gui/widgets/main_window.h"
+#include "gui/widgets/chord_arranger.h"
+#include "gui/widgets/chord_arranger_bg.h"
+#include "gui/widgets/ruler.h"
+#include "gui/widgets/piano_roll.h"
+#include "gui/widgets/ruler.h"
+#include "gui/widgets/tracklist.h"
+
+#include <gtk/gtk.h>
+
+G_DEFINE_TYPE (ChordArrangerBgWidget,
+ chord_arranger_bg_widget,
+ ARRANGER_BG_WIDGET_TYPE)
+
+static gboolean
+chord_arranger_draw_cb (
+ GtkWidget *widget,
+ cairo_t *cr,
+ gpointer data)
+{
+
+ return FALSE;
+}
+
+ChordArrangerBgWidget *
+chord_arranger_bg_widget_new (
+ RulerWidget * ruler,
+ ArrangerWidget * arranger)
+{
+ ChordArrangerBgWidget * self =
+ g_object_new (CHORD_ARRANGER_BG_WIDGET_TYPE,
+ NULL);
+
+ ARRANGER_BG_WIDGET_GET_PRIVATE (self);
+ ab_prv->ruler = ruler;
+ ab_prv->arranger = arranger;
+
+ g_signal_connect (
+ G_OBJECT (self), "draw",
+ G_CALLBACK (chord_arranger_draw_cb), NULL);
+
+ return self;
+}
+
+static void
+chord_arranger_bg_widget_class_init (
+ ChordArrangerBgWidgetClass * _klass)
+{
+}
+
+static void
+chord_arranger_bg_widget_init (
+ ChordArrangerBgWidget *self )
+{
+}
diff --git a/src/gui/widgets/chord_object.c b/src/gui/widgets/chord_object.c
index 5d846cc..e05962b 100644
--- a/src/gui/widgets/chord_object.c
+++ b/src/gui/widgets/chord_object.c
@@ -130,7 +130,7 @@ on_press (
DEFINE_ARRANGER_OBJECT_WIDGET_SELECT (
ChordObject, chord_object,
- timeline_selections, TL_SELECTIONS);
+ chord_selections, CHORD_SELECTIONS);
static gboolean
on_motion (
diff --git a/src/gui/widgets/chord_region.c b/src/gui/widgets/chord_region.c
new file mode 100644
index 0000000..244a6fb
--- /dev/null
+++ b/src/gui/widgets/chord_region.c
@@ -0,0 +1,86 @@
+/*
+ * Copyright (C) 2018-2019 Alexandros Theodotou <alex at zrythm dot org>
+ *
+ * This file is part of Zrythm
+ *
+ * Zrythm is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Zrythm 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 Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with Zrythm. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+#include "audio/bus_track.h"
+#include "audio/channel.h"
+#include "audio/chord_region.h"
+#include "audio/instrument_track.h"
+#include "audio/midi_note.h"
+#include "audio/track.h"
+#include "gui/backend/chord_selections.h"
+#include "gui/widgets/arranger.h"
+#include "gui/widgets/center_dock.h"
+#include "gui/widgets/main_window.h"
+#include "gui/widgets/midi_arranger.h"
+#include "gui/widgets/chord_region.h"
+#include "gui/widgets/region.h"
+#include "gui/widgets/ruler.h"
+#include "gui/widgets/timeline_arranger.h"
+#include "utils/cairo.h"
+
+G_DEFINE_TYPE (
+ ChordRegionWidget,
+ chord_region_widget,
+ REGION_WIDGET_TYPE)
+
+#define Y_PADDING 6.f
+#define Y_HALF_PADDING 3.f
+
+static gboolean
+chord_region_draw_cb (
+ GtkWidget * widget,
+ cairo_t *cr,
+ ChordRegionWidget * self)
+{
+
+ return FALSE;
+}
+
+ChordRegionWidget *
+chord_region_widget_new (
+ Region * region)
+{
+ ChordRegionWidget * self =
+ g_object_new (
+ CHORD_REGION_WIDGET_TYPE,
+ NULL);
+
+ region_widget_setup (
+ Z_REGION_WIDGET (self), region);
+ REGION_WIDGET_GET_PRIVATE (self);
+
+ /* connect signals */
+ g_signal_connect (
+ G_OBJECT (rw_prv->drawing_area), "draw",
+ G_CALLBACK (chord_region_draw_cb), self);
+
+ return self;
+}
+
+static void
+chord_region_widget_class_init (
+ ChordRegionWidgetClass * klass)
+{
+}
+
+static void
+chord_region_widget_init (
+ ChordRegionWidget * self)
+{
+}
diff --git a/src/gui/widgets/dzl/README b/src/gui/widgets/dzl/README
new file mode 100644
index 0000000..21b100d
--- /dev/null
+++ b/src/gui/widgets/dzl/README
@@ -0,0 +1 @@
+These are not part of Zrythm, but are used with Zrythm.
diff --git a/src/gui/widgets/dzl/meson.build b/src/gui/widgets/dzl/meson.build
index 404062b..fdac49d 100644
--- a/src/gui/widgets/dzl/meson.build
+++ b/src/gui/widgets/dzl/meson.build
@@ -1,3 +1,20 @@
+# Copyright (C) 2019 Alexandros Theodotou <alex at zrythm dot org>
+#
+# This file is part of Zrythm
+#
+# Zrythm is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Affero General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# Zrythm 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 Affero General Public License for more details.
+#
+# You should have received a copy of the GNU Affero General Public License
+# along with Zrythm. If not, see <https://www.gnu.org/licenses/>.
+
dzl_srcs = [
'dzl-animation.c',
'dzl-bin.c',
diff --git a/src/gui/widgets/gtk/README b/src/gui/widgets/gtk/README
new file mode 100644
index 0000000..21b100d
--- /dev/null
+++ b/src/gui/widgets/gtk/README
@@ -0,0 +1 @@
+These are not part of Zrythm, but are used with Zrythm.
diff --git a/src/gui/widgets/gtk/meson.build b/src/gui/widgets/gtk/meson.build
index a8025d9..c21bcca 100644
--- a/src/gui/widgets/gtk/meson.build
+++ b/src/gui/widgets/gtk/meson.build
@@ -1,3 +1,20 @@
+# Copyright (C) 2019 Alexandros Theodotou <alex at zrythm dot org>
+#
+# This file is part of Zrythm
+#
+# Zrythm is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Affero General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# Zrythm 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 Affero General Public License for more details.
+#
+# You should have received a copy of the GNU Affero General Public License
+# along with Zrythm. If not, see <https://www.gnu.org/licenses/>.
+
gtk_srcs = [
'gtkeventcontrollermotion.c',
]
diff --git a/src/gui/widgets/meson.build b/src/gui/widgets/meson.build
index eee5843..1a96fbb 100644
--- a/src/gui/widgets/meson.build
+++ b/src/gui/widgets/meson.build
@@ -1,3 +1,20 @@
+# Copyright (C) 2019 Alexandros Theodotou <alex at zrythm dot org>
+#
+# This file is part of Zrythm
+#
+# Zrythm is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Affero General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# Zrythm 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 Affero General Public License for more details.
+#
+# You should have received a copy of the GNU Affero General Public License
+# along with Zrythm. If not, see <https://www.gnu.org/licenses/>.
+
widget_srcs = [
'arranger_bg.c',
'arranger.c',
@@ -11,7 +28,10 @@ widget_srcs = [
'automatable_selector_button.c',
'automatable_selector_popover.c',
'automation_curve.c',
+ 'automation_arranger.c',
+ 'automation_arranger_bg.c',
'automation_point.c',
+ 'automation_region.c',
'automation_track.c',
'automation_tracklist.c',
'automator.c',
@@ -22,8 +42,11 @@ widget_srcs = [
'center_dock.c',
'channel.c',
'channel_slot.c',
+ 'chord_arranger.c',
+ 'chord_arranger_bg.c',
'chord_button.c',
'chord_object.c',
+ 'chord_region.c',
'chord_pad.c',
'chord_selector_window.c',
'chord_track.c',
diff --git a/src/gui/widgets/midi_arranger.c b/src/gui/widgets/midi_arranger.c
index 2f2c743..612da9e 100644
--- a/src/gui/widgets/midi_arranger.c
+++ b/src/gui/widgets/midi_arranger.c
@@ -149,7 +149,7 @@ midi_arranger_widget_get_note_at_y (double y)
}
MidiNoteWidget *
-midi_arranger_widget_get_hit_midi_note (
+midi_arranger_widget_get_hit_note (
MidiArrangerWidget * self,
double x,
double y)
@@ -215,7 +215,7 @@ on_motion (GtkWidget * widget,
}
void
-midi_arranger_widget_refresh_size (
+midi_arranger_widget_set_size (
MidiArrangerWidget * self)
{
// set the size
@@ -230,7 +230,7 @@ void
midi_arranger_widget_setup (
MidiArrangerWidget * self)
{
- midi_arranger_widget_refresh_size (self);
+ midi_arranger_widget_set_size (self);
ARRANGER_WIDGET_GET_PRIVATE (self);
g_signal_connect (
@@ -261,7 +261,7 @@ midi_arranger_widget_get_cursor (
tool == TOOL_EDIT)
{
MidiNoteWidget * mnw =
- midi_arranger_widget_get_hit_midi_note (
+ midi_arranger_widget_get_hit_note (
self,
ar_prv->hover_x,
ar_prv->hover_y);
@@ -358,7 +358,7 @@ midi_arranger_widget_show_context_menu (
GtkMenuItem * menu_item;
MidiNoteWidget * clicked_note =
- midi_arranger_widget_get_hit_midi_note (
+ midi_arranger_widget_get_hit_note (
self, x, y);
if (clicked_note)
@@ -566,7 +566,7 @@ midi_arranger_widget_create_note (
/* add it to region */
midi_region_add_midi_note (
- region, midi_note, F_GEN_WIDGET);
+ region, midi_note);
/* set visibility */
arranger_object_info_set_widget_visibility_and_state (
diff --git a/src/gui/widgets/midi_arranger_bg.c b/src/gui/widgets/midi_arranger_bg.c
index 8f80057..340df33 100644
--- a/src/gui/widgets/midi_arranger_bg.c
+++ b/src/gui/widgets/midi_arranger_bg.c
@@ -112,8 +112,9 @@ midi_arranger_draw_cb (
}
MidiArrangerBgWidget *
-midi_arranger_bg_widget_new (RulerWidget * ruler,
- ArrangerWidget * arranger)
+midi_arranger_bg_widget_new (
+ RulerWidget * ruler,
+ ArrangerWidget * arranger)
{
MidiArrangerBgWidget * self =
g_object_new (MIDI_ARRANGER_BG_WIDGET_TYPE,
diff --git a/src/gui/widgets/midi_modifier_arranger.c b/src/gui/widgets/midi_modifier_arranger.c
index c8a298e..77dc2a1 100644
--- a/src/gui/widgets/midi_modifier_arranger.c
+++ b/src/gui/widgets/midi_modifier_arranger.c
@@ -150,10 +150,10 @@ midi_modifier_arranger_widget_get_hit_velocity (
}
void
-midi_modifier_arranger_on_drag_begin_vel_hit (
+midi_modifier_arranger_widget_on_drag_begin_velocity_hit (
MidiModifierArrangerWidget * self,
- VelocityWidget * vel_w,
- double start_y)
+ double start_y,
+ VelocityWidget * vel_w)
{
ARRANGER_WIDGET_GET_PRIVATE (self);
@@ -219,9 +219,10 @@ midi_modifier_arranger_widget_select_all (
*/
void
midi_modifier_arranger_widget_show_context_menu (
- MidiModifierArrangerWidget * self)
+ MidiModifierArrangerWidget * self,
+ double x,
+ double y)
{
-
/* TODO */
}
diff --git a/src/gui/widgets/piano_roll.c b/src/gui/widgets/piano_roll.c
index 9343bac..60e86b1 100644
--- a/src/gui/widgets/piano_roll.c
+++ b/src/gui/widgets/piano_roll.c
@@ -200,7 +200,7 @@ piano_roll_widget_refresh (
0, 0, 0);
}
- midi_arranger_widget_refresh_size (
+ midi_arranger_widget_set_size (
MIDI_ARRANGER);
/* relink scrolls */
diff --git a/src/gui/widgets/timeline_arranger.c b/src/gui/widgets/timeline_arranger.c
index f03fbd7..f944446 100644
--- a/src/gui/widgets/timeline_arranger.c
+++ b/src/gui/widgets/timeline_arranger.c
@@ -30,6 +30,7 @@
#include "actions/undo_manager.h"
#include "actions/duplicate_timeline_selections_action.h"
#include "actions/move_timeline_selections_action.h"
+#include "audio/automation_region.h"
#include "audio/automation_track.h"
#include "audio/automation_tracklist.h"
#include "audio/audio_track.h"
@@ -50,6 +51,7 @@
#include "gui/widgets/automation_curve.h"
#include "gui/widgets/automation_track.h"
#include "gui/widgets/automation_point.h"
+#include "gui/widgets/automation_region.h"
#include "gui/widgets/bot_dock_edge.h"
#include "gui/widgets/center_dock.h"
#include "gui/widgets/chord_object.h"
@@ -155,113 +157,6 @@ timeline_arranger_widget_set_allocation (
GTK_WIDGET (tw_prv->top_grid));
}
}
- else if (Z_IS_AUTOMATION_POINT_WIDGET (widget))
- {
- AutomationPointWidget * ap_widget =
- Z_AUTOMATION_POINT_WIDGET (widget);
- AutomationPoint * ap =
- ap_widget->automation_point;
- /*Automatable * a = ap->at->automatable;*/
-
- gint wx, wy;
- if (!ap->at->created ||
- !ap->at->track->bot_paned_visible)
- return;
- gtk_widget_translate_coordinates (
- GTK_WIDGET (ap->at->widget),
- GTK_WIDGET (self),
- 0, 0, &wx, &wy);
-
- allocation->x =
- ui_pos_to_px_timeline (&ap->pos, 1) -
- AP_WIDGET_POINT_SIZE / 2;
- allocation->y =
- (wy + automation_point_get_y_in_px (ap)) -
- AP_WIDGET_POINT_SIZE / 2;
- allocation->width = AP_WIDGET_POINT_SIZE;
- allocation->height = AP_WIDGET_POINT_SIZE;
- }
- else if (Z_IS_AUTOMATION_CURVE_WIDGET (widget))
- {
- AutomationCurveWidget * acw =
- Z_AUTOMATION_CURVE_WIDGET (widget);
- AutomationCurve * ac = acw->ac;
- /*Automatable * a = ap->at->automatable;*/
-
- gint wx, wy;
- if (!ac->at->created ||
- !ac->at->track->bot_paned_visible)
- return;
- gtk_widget_translate_coordinates (
- GTK_WIDGET (ac->at->widget),
- GTK_WIDGET (self),
- 0, 0, &wx, &wy);
- AutomationPoint * prev_ap =
- automation_track_get_ap_before_curve (
- ac->at, ac);
- AutomationPoint * next_ap =
- automation_track_get_ap_after_curve (
- ac->at, ac);
- if (!prev_ap || !next_ap)
- g_return_if_reached ();
-
- allocation->x =
- ui_pos_to_px_timeline (
- &prev_ap->pos,
- 1) - AC_Y_HALF_PADDING;
- int prev_y =
- automation_point_get_y_in_px (prev_ap);
- int next_y =
- automation_point_get_y_in_px (next_ap);
- allocation->y =
- (wy + (prev_y > next_y ? next_y : prev_y) -
- AC_Y_HALF_PADDING);
- allocation->width =
- (ui_pos_to_px_timeline (
- &next_ap->pos,
- 1) - allocation->x) + AC_Y_HALF_PADDING;
- allocation->height =
- (prev_y > next_y ?
- prev_y - next_y :
- next_y - prev_y) + AC_Y_PADDING;
- }
- else if (Z_IS_CHORD_OBJECT_WIDGET (widget))
- {
- ChordObjectWidget * cw =
- Z_CHORD_OBJECT_WIDGET (widget);
- ChordObject * co =
- cw->chord_object;
- Track * track = P_CHORD_TRACK;
-
- gint wx, wy;
- gtk_widget_translate_coordinates (
- GTK_WIDGET (track->widget),
- GTK_WIDGET (self),
- 0, 0, &wx, &wy);
-
- allocation->x =
- ui_pos_to_px_timeline (
- &co->pos, 1);
- char * chord_str =
- chord_descriptor_to_string (co->descr);
- int textw, texth;
- z_cairo_get_text_extents_for_widget (
- widget, chord_str, &textw, &texth);
- g_free (chord_str);
- allocation->width =
- textw + CHORD_OBJECT_WIDGET_TRIANGLE_W +
- Z_CAIRO_TEXT_PADDING * 2;
-
- int track_height =
- gtk_widget_get_allocated_height (
- GTK_WIDGET (track->widget));
- int obj_height =
- texth + Z_CAIRO_TEXT_PADDING * 2;
- allocation->y =
- ((wy + track_height) - obj_height) -
- track_height / 2;
- allocation->height = obj_height;
- }
else if (Z_IS_SCALE_OBJECT_WIDGET (widget))
{
ScaleObjectWidget * cw =
@@ -349,18 +244,13 @@ timeline_arranger_widget_get_cursor (
self,
ar_prv->hover_x,
ar_prv->hover_y);
- ChordObjectWidget * cw =
- timeline_arranger_widget_get_hit_chord (
- self,
- ar_prv->hover_x,
- ar_prv->hover_y);
ScaleObjectWidget * sw =
timeline_arranger_widget_get_hit_scale (
self,
ar_prv->hover_x,
ar_prv->hover_y);
- int is_hit = rw || cw || sw;
+ int is_hit = rw || sw;
switch (action)
{
@@ -586,17 +476,11 @@ timeline_arranger_widget_get_hit_##sc ( \
}
GET_HIT_WIDGET (
- CHORD_OBJECT, ChordObject, chord);
-GET_HIT_WIDGET (
SCALE_OBJECT, ScaleObject, scale);
GET_HIT_WIDGET (
MARKER, Marker, marker);
GET_HIT_WIDGET (
REGION, Region, region);
-GET_HIT_WIDGET (
- AUTOMATION_POINT, AutomationPoint, ap);
-GET_HIT_WIDGET (
- AUTOMATION_CURVE, AutomationCurve, curve);
#undef GET_HIT_WIDGET
@@ -612,7 +496,6 @@ timeline_arranger_widget_select_all (
/* select everything else */
Region * r;
Track * track;
- AutomationPoint * ap;
AutomationTrack * at;
for (i = 0; i < TRACKLIST->num_tracks; i++)
{
@@ -650,38 +533,26 @@ timeline_arranger_widget_select_all (
{
at = atl->ats[j];
- if (!at->created)
+ if (!at->created ||
+ !at->visible)
continue;
- if (at->visible)
+ for (k = 0; k < at->num_regions; k++)
{
- for (k = 0;
- k < at->num_aps;
- k++)
- {
- ap =
- at->aps[k];
+ r = at->regions[k];
- automation_point_widget_select (
- ap->widget, select);
- }
+ region_widget_select (
+ r->widget, select);
}
}
}
- /* select chords */
- Track * ct = P_CHORD_TRACK;
- for (int i = 0; i < ct->num_chords; i++)
- {
- ChordObject * chord = ct->chords[i];
- chord_object_widget_select (
- chord->widget, select);
- }
-
/* select scales */
- for (int i = 0; i < ct->num_scales; i++)
+ ScaleObject * scale;
+ for (int i = 0;
+ i < P_CHORD_TRACK->num_scales; i++)
{
- ScaleObject * scale = ct->scales[i];
+ scale = P_CHORD_TRACK->scales[i];
scale_object_widget_select (
scale->widget, select);
}
@@ -711,9 +582,6 @@ timeline_arranger_widget_show_context_menu (
/*RegionWidget * clicked_region =*/
/*timeline_arranger_widget_get_hit_region (*/
/*self, x, y);*/
- /*ChordWidget * clicked_chord =*/
- /*timeline_arranger_widget_get_hit_chord (*/
- /*self, x, y);*/
/*AutomationPointWidget * clicked_ap =*/
/*timeline_arranger_widget_get_hit_ap (*/
/*self, x, y);*/
@@ -751,14 +619,6 @@ timeline_arranger_widget_update_visibility (
TL_SELECTIONS->num_regions,
Region, region);
ARRANGER_SET_OBJ_VISIBILITY_ARRAY (
- TL_SELECTIONS->automation_points,
- TL_SELECTIONS->num_automation_points,
- AutomationPoint, automation_point);
- ARRANGER_SET_OBJ_VISIBILITY_ARRAY (
- TL_SELECTIONS->chord_objects,
- TL_SELECTIONS->num_chord_objects,
- ChordObject, chord_object);
- ARRANGER_SET_OBJ_VISIBILITY_ARRAY (
TL_SELECTIONS->scale_objects,
TL_SELECTIONS->num_scale_objects,
ScaleObject, scale_object);
@@ -875,50 +735,6 @@ timeline_arranger_widget_on_drag_begin_region_hit (
}
}
}
-
-void
-timeline_arranger_widget_on_drag_begin_chord_hit (
- TimelineArrangerWidget * self,
- double start_x,
- ChordObjectWidget * cw)
-{
- ARRANGER_WIDGET_GET_PRIVATE (self);
-
- ChordObject * chord = cw->chord_object;
- self->start_chord = chord;
-
- /* update arranger action */
- ar_prv->action =
- UI_OVERLAY_ACTION_STARTING_MOVING;
- /* FIXME cursor should be set automatically */
- ui_set_cursor_from_name (
- GTK_WIDGET (cw), "grabbing");
-
- int selected = chord_object_is_selected (chord);
-
- /* select chord if unselected */
- if (P_TOOL == TOOL_SELECT_NORMAL ||
- P_TOOL == TOOL_SELECT_STRETCH ||
- P_TOOL == TOOL_EDIT)
- {
- /* if ctrl held & not selected, add to
- * selections */
- if (ar_prv->ctrl_held && !selected)
- {
- ARRANGER_WIDGET_SELECT_CHORD (
- self, chord, F_SELECT, F_APPEND);
- }
- /* if ctrl not held & not selected, make it
- * the only selection */
- else if (!ar_prv->ctrl_held &&
- !selected)
- {
- ARRANGER_WIDGET_SELECT_CHORD (
- self, chord, F_SELECT, F_NO_APPEND);
- }
- }
-}
-
void
timeline_arranger_widget_on_drag_begin_scale_hit (
TimelineArrangerWidget * self,
@@ -1006,110 +822,21 @@ timeline_arranger_widget_on_drag_begin_marker_hit (
}
-void
-timeline_arranger_widget_on_drag_begin_ap_hit (
- TimelineArrangerWidget * self,
- double start_x,
- AutomationPointWidget * ap_widget)
-{
- ARRANGER_WIDGET_GET_PRIVATE (self);
-
- AutomationPoint * ap =
- ap_widget->automation_point;
- ar_prv->start_pos_px = start_x;
- self->start_ap = ap;
- if (!array_contains (
- TL_SELECTIONS->automation_points,
- TL_SELECTIONS->num_automation_points,
- ap))
- {
- TL_SELECTIONS->automation_points[0] =
- ap;
- TL_SELECTIONS->num_automation_points =
- 1;
- }
-
- self->start_ap = ap;
-
- /* update arranger action */
- ar_prv->action =
- UI_OVERLAY_ACTION_STARTING_MOVING;
- ui_set_cursor_from_name (GTK_WIDGET (ap_widget),
- "grabbing");
-
- /* update selection */
- if (ar_prv->ctrl_held)
- {
- ARRANGER_WIDGET_SELECT_AUTOMATION_POINT (
- self, ap, F_SELECT, F_APPEND);
- }
- else
- {
- timeline_arranger_widget_select_all (self, 0);
- ARRANGER_WIDGET_SELECT_AUTOMATION_POINT (
- self, ap, F_SELECT, F_NO_APPEND);
- }
-}
-
-/**
- * Create an AutomationPointat the given Position
- * in the given Track's AutomationTrack.
- *
- * @param pos The pre-snapped position.
- */
-void
-timeline_arranger_widget_create_ap (
- TimelineArrangerWidget * self,
- AutomationTrack * at,
- const Position * pos,
- const double start_y)
-{
- g_warn_if_fail (at);
- ARRANGER_WIDGET_GET_PRIVATE (self);
-
- float value =
- automation_track_widget_get_fvalue_at_y (
- at->widget, start_y);
-
- ar_prv->action =
- UI_OVERLAY_ACTION_CREATING_MOVING;
-
- /* create a new ap */
- AutomationPoint * ap =
- automation_point_new_float (
- value, pos, F_MAIN);
- self->start_ap = ap;
-
- /* add it to automation track */
- automation_track_add_ap (
- at, ap, F_GEN_WIDGET, F_GEN_CURVE_POINTS);
-
- /* set visibility */
- arranger_object_info_set_widget_visibility_and_state (
- &ap->obj_info, 1);
-
- /* set position to all counterparts */
- automation_point_set_pos (
- ap, pos, AO_UPDATE_ALL);
-
- EVENTS_PUSH (
- ET_AUTOMATION_POINT_CREATED, ap);
- ARRANGER_WIDGET_SELECT_AUTOMATION_POINT (
- self, ap, F_SELECT,
- F_NO_APPEND);
-}
-
/**
* Create a Region at the given Position in the
* given Track's given TrackLane.
*
* @param pos The pre-snapped position.
+ * @param track Track, if non-automation.
+ * @param lane TrackLane, if midi/audio region.
+ * @param at AutomationTrack, if automation Region.
*/
void
timeline_arranger_widget_create_region (
TimelineArrangerWidget * self,
- Track * track,
- TrackLane * lane,
+ Track * track,
+ TrackLane * lane,
+ AutomationTrack * at,
const Position * pos)
{
if (track->type == TRACK_TYPE_AUDIO)
@@ -1155,11 +882,10 @@ timeline_arranger_widget_create_region (
if (track->type == TRACK_TYPE_INSTRUMENT)
{
track_add_region (
- track, region,
+ track, region, NULL,
lane ? lane->pos :
(track->num_lanes == 1 ?
- 0 : track->num_lanes - 2), F_GEN_NAME,
- F_GEN_WIDGET);
+ 0 : track->num_lanes - 2), F_GEN_NAME);
/* set visibility */
arranger_object_info_set_widget_visibility_and_state (
@@ -1207,8 +933,8 @@ timeline_arranger_widget_create_chord_or_scale (
}
/**
- * Create a ChordObject at the given Position in the
- * given Track.
+ * Create a chord Region at the given Position in
+ * the given Track.
*
* @param pos The pre-snapped position.
*/
@@ -1225,29 +951,8 @@ timeline_arranger_widget_create_chord (
ar_prv->action =
UI_OVERLAY_ACTION_CREATING_MOVING;
- /* create a new chord */
- ChordDescriptor * descr =
- chord_descriptor_new (
- NOTE_B, 1, NOTE_B, CHORD_TYPE_MIN,
- CHORD_ACC_7, 0);
- ChordObject * chord =
- chord_object_new (
- descr, 1);
-
- /* add it to chord track */
- chord_track_add_chord (track, chord, 1);
-
- /* set visibility */
- arranger_object_info_set_widget_visibility_and_state (
- &chord->obj_info, 1);
-
- chord_object_set_pos (
- chord, pos, AO_UPDATE_ALL);
-
- EVENTS_PUSH (ET_CHORD_OBJECT_CREATED, chord);
- ARRANGER_WIDGET_SELECT_CHORD (
- self, chord, F_SELECT,
- F_NO_APPEND);
+ /* create a new chord region */
+ /* TODO */
}
/**
@@ -1278,7 +983,7 @@ timeline_arranger_widget_create_scale (
descr, 1);
/* add it to scale track */
- chord_track_add_scale (track, scale, 1);
+ chord_track_add_scale (track, scale);
/* set visibility */
arranger_object_info_set_widget_visibility_and_state (
@@ -1320,7 +1025,7 @@ timeline_arranger_widget_create_marker (
/* add it to marker track */
marker_track_add_marker (
- track, marker, F_GEN_WIDGET);
+ track, marker);
/* set visibility */
arranger_object_info_set_widget_visibility_and_state (
@@ -1450,27 +1155,6 @@ timeline_arranger_widget_select (
}
FIND_ENCLOSED_WIDGETS_OF_TYPE (
- CHORD_OBJECT, ChordObject, chord_object);
- for (i = 0; i < num_chord_object_widgets; i++)
- {
- chord_object_widget =
- Z_CHORD_OBJECT_WIDGET (
- chord_object_widgets[i]);
-
- chord_object =
- chord_object_get_main_chord_object (
- chord_object_widget->chord_object);
-
- if (delete)
- chord_track_remove_chord (
- P_CHORD_TRACK,
- chord_object, F_FREE);
- else
- ARRANGER_WIDGET_SELECT_CHORD (
- self, chord_object, F_SELECT, F_APPEND);
- }
-
- FIND_ENCLOSED_WIDGETS_OF_TYPE (
SCALE_OBJECT, ScaleObject, scale_object);
for (i = 0; i < num_scale_object_widgets; i++)
{
@@ -1511,29 +1195,6 @@ timeline_arranger_widget_select (
self, marker, F_SELECT, F_APPEND);
}
- /* find enclosed automation_points */
- FIND_ENCLOSED_WIDGETS_OF_TYPE (
- AUTOMATION_POINT, AutomationPoint,
- automation_point);
- for (i = 0; i < num_automation_point_widgets; i++)
- {
- automation_point_widget =
- Z_AUTOMATION_POINT_WIDGET (
- automation_point_widgets[i]);
-
- automation_point =
- automation_point_get_main_automation_point (
- automation_point_widget->automation_point);
-
- if (delete)
- automation_track_remove_ap (
- automation_point->at,
- automation_point, F_FREE);
- else
- ARRANGER_WIDGET_SELECT_AUTOMATION_POINT (
- self, automation_point, F_SELECT, F_APPEND);
- }
-
#undef FIND_ENCLOSED_WIDGETS_OF_TYPE
}
@@ -1901,21 +1562,15 @@ update_last_timeline_object ()
Track * track;
Region * region;
- AutomationPoint * ap;
for (int i = 0; i < TRACKLIST->num_tracks; i++)
{
track = TRACKLIST->tracks[i];
region =
track_get_last_region (track);
- ap =
- track_get_last_automation_point (track);
if (region)
COMPARE_AND_SET (&region->end_pos);
-
- if (ap)
- COMPARE_AND_SET (&ap->pos);
}
if (prev != self->last_timeline_obj_bars &&
@@ -2013,9 +1668,8 @@ timeline_arranger_widget_move_items_y (
old_track,
region, F_NO_FREE);
track_add_region (
- nt, region, 0,
- F_NO_GEN_NAME,
- F_NO_GEN_WIDGET);
+ nt, region, NULL,
+ 0, F_NO_GEN_NAME);
}
else if (nt->type ==
TRACK_TYPE_AUDIO)
@@ -2067,61 +1721,6 @@ timeline_arranger_widget_move_items_y (
}
}
}
- else if (TL_SELECTIONS->num_automation_points)
- {
- for (int i = 0;
- i < TL_SELECTIONS->
- num_automation_points; i++)
- {
- AutomationPoint * ap =
- TL_SELECTIONS->
- automation_points[i];
-
- ap = automation_point_get_main_automation_point (ap);
-
- float fval =
- automation_track_widget_get_fvalue_at_y (
- ap->at->widget,
- ar_prv->start_y + offset_y);
- automation_point_update_fvalue (
- ap, fval, AO_UPDATE_TRANS);
- }
- automation_point_widget_update_tooltip (
- self->start_ap->widget, 1);
- }
-}
-
-/**
- * Returns the ticks objects were moved by since
- * the start of the drag.
- *
- * FIXME not really needed, can use
- * timeline_selections_get_start_pos and the
- * arranger's earliest_obj_start_pos.
- */
-static long
-get_moved_diff (
- TimelineArrangerWidget * self)
-{
-#define GET_DIFF(sc,pos_name) \
- if (TL_SELECTIONS->num_##sc##s) \
- { \
- return \
- position_to_ticks ( \
- &sc##_get_main_trans_##sc ( \
- TL_SELECTIONS->sc##s[0])->pos_name) - \
- position_to_ticks ( \
- &sc##_get_main_##sc ( \
- TL_SELECTIONS->sc##s[0])->pos_name); \
- }
-
- GET_DIFF (region, start_pos);
- GET_DIFF (marker, pos);
- GET_DIFF (chord_object, pos);
- GET_DIFF (scale_object, pos);
- GET_DIFF (automation_point, pos);
-
- g_return_val_if_reached (0);
}
/**
@@ -2134,17 +1733,6 @@ timeline_arranger_widget_on_drag_end (
{
ARRANGER_WIDGET_GET_PRIVATE (self);
- AutomationPoint * ap;
- for (int i = 0;
- i < TL_SELECTIONS->
- num_automation_points; i++)
- {
- ap =
- TL_SELECTIONS->automation_points[i];
- automation_point_widget_update_tooltip (
- ap->widget, 0);
- }
-
if (ar_prv->action ==
UI_OVERLAY_ACTION_RESIZING_L)
{
@@ -2300,9 +1888,7 @@ timeline_arranger_widget_on_drag_end (
self->resizing_range = 0;
self->resizing_range_start = 0;
self->start_region = NULL;
- self->start_ap = NULL;
self->start_region_was_selected = 0;
- self->start_ap = NULL;
EVENTS_PUSH (ET_TL_SELECTIONS_CHANGED,
NULL);
@@ -2320,6 +1906,7 @@ add_children_from_channel_track (
AutomationTracklist * atl =
&ct->automation_tracklist;
AutomationTrack * at;
+ Region * region;
for (i = 0; i < atl->num_ats; i++)
{
at = atl->ats[i];
@@ -2327,39 +1914,31 @@ add_children_from_channel_track (
if (!at->created || !at->visible)
continue;
- for (j = 0; j < at->num_aps; j++)
- {
- AutomationPoint * ap =
- at->aps[j];
+ for (j = 0; j < at->num_regions; j++)
+ {
+ region = at->regions[j];
for (k = 0; k < 2; k++)
{
if (k == 0)
- ap = automation_point_get_main_automation_point (ap);
+ region =
+ region_get_main_region (region);
else if (k == 1)
- ap = automation_point_get_main_trans_automation_point (ap);
+ region =
+ region_get_main_trans_region (
+ region);
- if (!GTK_IS_WIDGET (ap->widget))
- ap->widget =
- automation_point_widget_new (ap);
+ if (!GTK_IS_WIDGET (region->widget))
+ region->widget =
+ Z_REGION_WIDGET (
+ automation_region_widget_new (
+ region));
gtk_overlay_add_overlay (
GTK_OVERLAY (MW_TIMELINE),
- GTK_WIDGET (ap->widget));
+ GTK_WIDGET (region->widget));
}
}
- for (j = 0; j < at->num_acs; j++)
- {
- AutomationCurve * ac =
- at->acs[j];
- if (!GTK_IS_WIDGET (ac->widget))
- ac->widget =
- automation_curve_widget_new (ac);
-
- gtk_overlay_add_overlay (
- GTK_OVERLAY (MW_TIMELINE),
- GTK_WIDGET (ac->widget));
- }
}
}
@@ -2369,26 +1948,6 @@ add_children_from_chord_track (
ChordTrack * ct)
{
int i, k;
- for (i = 0; i < ct->num_chords; i++)
- {
- ChordObject * c = ct->chords[i];
- for (k = 0 ; k < 2; k++)
- {
- if (k == 0)
- c = chord_object_get_main_chord_object (c);
- else if (k == 1)
- c = chord_object_get_main_trans_chord_object (c);
-
- if (!c->widget)
- c->widget =
- chord_object_widget_new (c);
-
- gtk_overlay_add_overlay (
- GTK_OVERLAY (self),
- GTK_WIDGET (c->widget));
- }
- }
-
for (i = 0; i < ct->num_scales; i++)
{
ScaleObject * c = ct->scales[i];
diff --git a/src/gui/widgets/transport_controls.c b/src/gui/widgets/transport_controls.c
index 04da9aa..5a87ab7 100644
--- a/src/gui/widgets/transport_controls.c
+++ b/src/gui/widgets/transport_controls.c
@@ -89,12 +89,16 @@ static void
backward_clicked_cb (GtkButton * backward,
gpointer user_data)
{
- Position *pos = snap_grid_get_nearby_snap_point(&PROJECT->snap_grid_timeline, &TRANSPORT->playhead_pos, 1);
- transport_move_playhead(pos, 1);
+ Position * pos =
+ snap_grid_get_nearby_snap_point (
+ &PROJECT->snap_grid_timeline,
+ &TRANSPORT->playhead_pos, 1);
+ transport_move_playhead (pos, 1);
}
/**
- * Initializes the transport controls in the main window.
+ * Initializes the transport controls in the main
+ * window.
*/
void
transport_controls_widget_refresh (MainWindowWidget * mw)
diff --git a/src/meson.build b/src/meson.build
index 3a75ea4..1667264 100644
--- a/src/meson.build
+++ b/src/meson.build
@@ -1,3 +1,20 @@
+# Copyright (C) 2019 Alexandros Theodotou <alex at zrythm dot org>
+#
+# This file is part of Zrythm
+#
+# Zrythm is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Affero General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# Zrythm 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 Affero General Public License for more details.
+#
+# You should have received a copy of the GNU Affero General Public License
+# along with Zrythm. If not, see <https://www.gnu.org/licenses/>.
+
gen_gtk_gresources = find_program (
join_paths (
resources_dir, 'gen-gtk-gresources-xml.py'))
diff --git a/src/plugins/lv2/meson.build b/src/plugins/lv2/meson.build
index 7bd3b83..42ae5c4 100644
--- a/src/plugins/lv2/meson.build
+++ b/src/plugins/lv2/meson.build
@@ -1,3 +1,20 @@
+# Copyright (C) 2019 Alexandros Theodotou <alex at zrythm dot org>
+#
+# This file is part of Zrythm
+#
+# Zrythm is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Affero General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# Zrythm 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 Affero General Public License for more details.
+#
+# You should have received a copy of the GNU Affero General Public License
+# along with Zrythm. If not, see <https://www.gnu.org/licenses/>.
+
lv2_srcs = [
'control.c',
'jack.c',
diff --git a/src/plugins/meson.build b/src/plugins/meson.build
index 20622b8..6c1ed5a 100644
--- a/src/plugins/meson.build
+++ b/src/plugins/meson.build
@@ -1,3 +1,20 @@
+# Copyright (C) 2019 Alexandros Theodotou <alex at zrythm dot org>
+#
+# This file is part of Zrythm
+#
+# Zrythm is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Affero General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# Zrythm 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 Affero General Public License for more details.
+#
+# You should have received a copy of the GNU Affero General Public License
+# along with Zrythm. If not, see <https://www.gnu.org/licenses/>.
+
plugin_srcs = [
'lv2_gtk.c',
'lv2_plugin.c',
diff --git a/src/settings/meson.build b/src/settings/meson.build
index a886bb4..70c8dee 100644
--- a/src/settings/meson.build
+++ b/src/settings/meson.build
@@ -1,3 +1,20 @@
+# Copyright (C) 2019 Alexandros Theodotou <alex at zrythm dot org>
+#
+# This file is part of Zrythm
+#
+# Zrythm is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Affero General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# Zrythm 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 Affero General Public License for more details.
+#
+# You should have received a copy of the GNU Affero General Public License
+# along with Zrythm. If not, see <https://www.gnu.org/licenses/>.
+
settings_srcs = [
'settings.c',
]
diff --git a/src/utils/meson.build b/src/utils/meson.build
index 9bc4f32..85e0c8c 100644
--- a/src/utils/meson.build
+++ b/src/utils/meson.build
@@ -1,3 +1,20 @@
+# Copyright (C) 2019 Alexandros Theodotou <alex at zrythm dot org>
+#
+# This file is part of Zrythm
+#
+# Zrythm is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Affero General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# Zrythm 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 Affero General Public License for more details.
+#
+# You should have received a copy of the GNU Affero General Public License
+# along with Zrythm. If not, see <https://www.gnu.org/licenses/>.
+
util_srcs = [
'arrays.c',
'audio.c',
diff --git a/src/utils/ui.c b/src/utils/ui.c
index 7ba1bbc..9299b0f 100644
--- a/src/utils/ui.c
+++ b/src/utils/ui.c
@@ -327,6 +327,30 @@ ui_pos_to_px_audio_clip_editor (
pos, use_padding, Z_RULER_WIDGET (AUDIO_RULER));
}
+int
+ui_pos_to_px_chord_editor (
+ Position * pos,
+ int use_padding)
+{
+ if (!MAIN_WINDOW || !MIDI_RULER)
+ return 0;
+
+ return pos_to_px (
+ pos, use_padding, Z_RULER_WIDGET (MIDI_RULER));
+}
+
+int
+ui_pos_to_px_automation_editor (
+ Position * pos,
+ int use_padding)
+{
+ if (!MAIN_WINDOW || !MIDI_RULER)
+ return 0;
+
+ return pos_to_px (
+ pos, use_padding, Z_RULER_WIDGET (MIDI_RULER));
+}
+
static long
px_to_frames (
double px,
diff --git a/tests/audio/automation_track.c b/tests/audio/automation_track.c
index 53f1afc..95667a2 100644
--- a/tests/audio/automation_track.c
+++ b/tests/audio/automation_track.c
@@ -19,6 +19,7 @@
#include "audio/channel.h"
#include "audio/automatable.h"
+#include "audio/automation_region.h"
#include "audio/automation_track.h"
#include "project.h"
#include "utils/arrays.h"
diff --git a/tests/meson.build b/tests/meson.build
index 479f124..d6e26da 100644
--- a/tests/meson.build
+++ b/tests/meson.build
@@ -1,3 +1,20 @@
+# Copyright (C) 2019 Alexandros Theodotou <alex at zrythm dot org>
+#
+# This file is part of Zrythm
+#
+# Zrythm is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Affero General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# Zrythm 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 Affero General Public License for more details.
+#
+# You should have received a copy of the GNU Affero General Public License
+# along with Zrythm. If not, see <https://www.gnu.org/licenses/>.
+
if get_option ('enable_tests')
test_env = environment ()
diff --git a/tools/.clang-format b/tools/.clang-format
index 6e9288b..7c3230d 100644
--- a/tools/.clang-format
+++ b/tools/.clang-format
@@ -1,3 +1,20 @@
+# Copyright (C) 2019 Alexandros Theodotou <alex at zrythm dot org>
+#
+# This file is part of Zrythm
+#
+# Zrythm is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Affero General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# Zrythm 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 Affero General Public License for more details.
+#
+# You should have received a copy of the GNU Affero General Public License
+# along with Zrythm. If not, see <https://www.gnu.org/licenses/>.
+
---
Language: Cpp
AccessModifierOffset: -2