30 Commits
0.3.0 ... 0.3.2

Author SHA1 Message Date
Tom A. Wagner
c1ec56e115 Release 0.3.2 2021-11-30 18:25:58 +01:00
Tom A. Wagner
110e9ef67f meson: Add dist script to vendor cargo dependencies for offline builds 2021-11-30 09:59:56 +01:00
Jan Beich
3c507683b7 build-aux: relax shebang in cargo.sh after 7b1b5ea336
/bin/sh: /bin/bash: not found
2021-11-27 21:57:03 +00:00
Thomas Rosendal
1d1f8bd3d7 Add instruction to add the flatpak remote 'flathub' 2021-11-25 07:59:45 +00:00
Sebastian Grabowski
b25f6f9abb Update the extension versions in flatpak build instructions to 21.08
The extensions need to match the SDK version, that was updated to
org.gnome.Sdk//41 in Commit e5e02b13. (Version 41 is based on
org.freedesktop.Sdk//21.08)
2021-11-24 17:03:23 +01:00
Tom A. Wagner
2d51ea677e ci: use more recent fd.o ci-templates 2021-11-24 16:11:16 +01:00
Tom A. Wagner
beb03d8b09 Update CI container for rust 1.56 2021-11-24 16:11:16 +01:00
Tom A. Wagner
502cf4476b gtk4dep: bump to 4.4 for fixed gtk_pick when using affine transform
This will be needed in a later commit for zooming in on the canvas using an affine (scaling) transformation matrix
2021-11-24 16:11:16 +01:00
Tom A. Wagner
eac973da15 Swap to rust 2021 edition and move rustc version check from meson.build to Cargo.toml 2021-11-24 16:11:16 +01:00
Tom A. Wagner
82a3e4f900 graphview: draw background automatically
This removes the manual painting of the background via cairo and adds the correct color to CSS instead,
which should hopefully improve performance as we do less cpu painting like this.
2021-11-24 16:11:16 +01:00
Suchipi
2cfc8e2e6f Update build instructions to match changes in e5e02b1387 2021-11-19 01:10:14 +00:00
Tom A. Wagner
e5e02b1387 flatpak: Update to gnome runtime 41 2021-11-17 19:49:52 +01:00
Tom A. Wagner
396363cef1 README: Update screenshot 2021-11-17 19:49:52 +01:00
Tom A. Wagner
c887d77f64 graphview: Use #808080 as link color
For good contrast in both dark and light mode, the link color is now a semi-light gray instead of complete black, which had bad contrast in dark mode and good constrast in light mode.

Later, we can seperate color palettes for light and dark mode, but only together with a dark mode toggle button or system-wide darkmode toggle.
2021-11-13 20:32:40 +01:00
Tom A. Wagner
54d7ca83ae graphview: Define link and grid colors in style.css
Previously, these were defined directly in the code,
but defining them in the css helps seperating theming and behaviour
and makes the colors easier to tweak.
2021-11-13 20:08:47 +01:00
Tom A. Wagner
7b1b5ea336 build: fix and improve cargo.sh
cargo.sh previously used bash features but only used `sh` in the shebang,
and also did not properly quote some variables to avoid splitting/globbing from happening.

Also, `-euo pilefail` is now set to avoid other errors that might come up.
2021-10-26 10:04:07 +02:00
Tom A. Wagner
729d4e1555 CI: Update container 2021-10-13 12:11:06 +02:00
Tom A. Wagner
ce6cab8134 Run rustfmt 2021-10-13 12:01:22 +02:00
Tom A. Wagner
8a552d0712 graphview: Add missing }; to fix build. 2021-10-13 11:56:46 +02:00
halfbro
f76235674c Add small control point offset to links that connect from right to left (loopbacks) 2021-10-13 09:11:10 +00:00
Tom A. Wagner
92dcfd61a1 Add gpl snippets to the start of each rust source file. 2021-10-03 11:27:36 +02:00
Tom A. Wagner
02e58e9bfa LICENSE: Replace outdated and edited GPL with the lastest stock version.
The old license file contained project specific edits, but editing the GPL text is disallowed by the fsf.
The new file also contains updated links.
2021-10-03 11:14:30 +02:00
Tom A. Wagner
958fa15230 Release 0.3.1 2021-09-30 08:45:11 +02:00
Tom A. Wagner
e9753dd078 Update dependencies 2021-09-30 08:45:00 +02:00
Tom A. Wagner
dfb1b754c7 Add and install icons.
This adds one new app icon and one new symbolic icon, and makes meson install these to the appropriate
directories, and adds an appropriate entry in the .desktop file.
2021-09-30 08:28:06 +02:00
Tom A. Wagner
497da8b953 graphview: Do not crash when the position of a node not on the graph is requested
While the position of a node not on the graph should never be requested, this seems to occur sometimes,
so instead of panicking, we only log an error now, or ignore that node if it wasn't
important.
2021-09-11 15:03:03 +02:00
Tom A. Wagner
da5da90352 Add .desktop file
This adds a .desktop file (without icon for now), which will automatically be installed when
`meson install` is run.
2021-08-29 18:41:09 +02:00
Tom A. Wagner
a8bfd8383e buildsystem: Move to meson for building the project
Meson will allow us to:
- Verify the used rust compiler is recent enough
- Install ressources such as a .desktop files, icons, etc.
2021-08-29 17:28:55 +02:00
Tom A. Wagner
7ef8677c4c readme: move screenshot.png into docs/ folder 2021-08-29 16:56:56 +02:00
Roger Roger
487dc3b2d3 Group nodes into columns by major type 2021-08-18 07:23:50 +00:00
29 changed files with 4054 additions and 180 deletions

View File

@@ -1,6 +1,6 @@
include:
- project: 'freedesktop/ci-templates' # the project to include from
ref: '98f557799157ebb0395cf11d40f01f61fbbace20' # git ref of that project
ref: '34f4ade99434043f88e164933f570301fd18b125' # git ref of that project
file: '/templates/fedora.yml' # the actual file to include
stages:
@@ -15,9 +15,9 @@ variables:
# Version and tag for our current container
.fedora:
variables:
FDO_DISTRIBUTION_VERSION: '34'
FDO_DISTRIBUTION_VERSION: '35'
# Update this to trigger a container rebuild
FDO_DISTRIBUTION_TAG: '2021-05-06.0'
FDO_DISTRIBUTION_TAG: '2021-11-23.0'
build-fedora-container:
extends:

192
Cargo.lock generated
View File

@@ -22,9 +22,9 @@ dependencies = [
[[package]]
name = "anyhow"
version = "1.0.42"
version = "1.0.44"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "595d3cfa7a60d4555cb5067b99f07142a08ea778de5cf993f7b75c7d8fabc486"
checksum = "61604a8f862e1d5c3229fdd78f8b02c68dcf73a4c4b05fd636d12240aaa242c1"
[[package]]
name = "arrayvec"
@@ -74,9 +74,9 @@ dependencies = [
[[package]]
name = "bitflags"
version = "1.2.1"
version = "1.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693"
checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
[[package]]
name = "bitvec"
@@ -92,9 +92,9 @@ dependencies = [
[[package]]
name = "cairo-rs"
version = "0.14.1"
version = "0.14.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a408c13bbc04c3337b94194c1a4d04067097439b79dbc1dcbceba299d828b9ea"
checksum = "9164355c892b026d6257e696dde5f3cb39beb3718297f0f161b562fe2ee3ab86"
dependencies = [
"bitflags",
"cairo-sys-rs",
@@ -111,14 +111,14 @@ checksum = "d7c9c3928781e8a017ece15eace05230f04b647457d170d2d9641c94a444ff80"
dependencies = [
"glib-sys",
"libc",
"system-deps",
"system-deps 3.2.0",
]
[[package]]
name = "cc"
version = "1.0.69"
version = "1.0.70"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e70cc2f62c6ce1868963827bd677764c62d07c3d9a3e1fb1177ee1a9ab199eb2"
checksum = "d26a6ce4b6a484fa3edb70f7efa6fc430fd2b87285fe8b84304fd0936faa0dc0"
[[package]]
name = "cexpr"
@@ -138,6 +138,15 @@ dependencies = [
"smallvec",
]
[[package]]
name = "cfg-expr"
version = "0.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "edae0b9625d1fce32f7d64b71784d9b1bf8469ec1a9c417e44aaf16a9cbd7571"
dependencies = [
"smallvec",
]
[[package]]
name = "cfg-if"
version = "0.1.10"
@@ -152,9 +161,9 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
[[package]]
name = "clang-sys"
version = "1.2.0"
version = "1.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "853eda514c284c2287f4bf20ae614f8781f40a81d32ecda6e91449304dfe077c"
checksum = "10612c0ec0e0a1ff0e97980647cb058a6e7aedb913d01d009c406b8b7d0b26ee"
dependencies = [
"glob",
"libc",
@@ -227,11 +236,11 @@ dependencies = [
[[package]]
name = "errno-dragonfly"
version = "0.1.1"
version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "14ca354e36190500e1e1fb267c647932382b54053c50b14970856c0b00a35067"
checksum = "aa68f1b12764fab894d2755d2518754e71b4fd80ecfb822714a1206c2aab39bf"
dependencies = [
"gcc",
"cc",
"libc",
]
@@ -253,24 +262,24 @@ checksum = "fed34cd105917e91daa4da6b3728c47b068749d6a62c59811f06ed2ac71d9da7"
[[package]]
name = "futures-channel"
version = "0.3.16"
version = "0.3.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "74ed2411805f6e4e3d9bc904c95d5d423b89b3b25dc0250aa74729de20629ff9"
checksum = "5da6ba8c3bb3c165d3c7319fc1cc8304facf1fb8db99c5de877183c08a273888"
dependencies = [
"futures-core",
]
[[package]]
name = "futures-core"
version = "0.3.16"
version = "0.3.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "af51b1b4a7fdff033703db39de8802c673eb91855f2e0d47dcf3bf2c0ef01f99"
checksum = "88d1c26957f23603395cd326b0ffe64124b818f4449552f960d815cfba83a53d"
[[package]]
name = "futures-executor"
version = "0.3.16"
version = "0.3.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4d0d535a57b87e1ae31437b892713aee90cd2d7b0ee48727cd11fc72ef54761c"
checksum = "45025be030969d763025784f7f355043dc6bc74093e4ecc5000ca4dc50d8745c"
dependencies = [
"futures-core",
"futures-task",
@@ -279,21 +288,21 @@ dependencies = [
[[package]]
name = "futures-io"
version = "0.3.16"
version = "0.3.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0b0e06c393068f3a6ef246c75cdca793d6a46347e75286933e5e75fd2fd11582"
checksum = "522de2a0fe3e380f1bc577ba0474108faf3f6b18321dbf60b3b9c39a75073377"
[[package]]
name = "futures-task"
version = "0.3.16"
version = "0.3.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bbe54a98670017f3be909561f6ad13e810d9a51f3f061b902062ca3da80799f2"
checksum = "1d3d00f4eddb73e498a54394f228cd55853bdf059259e8e7bc6e69d408892e99"
[[package]]
name = "futures-util"
version = "0.3.16"
version = "0.3.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "67eb846bfd58e44a8481a00049e82c43e0ccb5d61f8dc071057cb19249dd4d78"
checksum = "36568465210a3a6ee45e1f165136d68671471a501e632e9a98d96872222b5481"
dependencies = [
"autocfg",
"futures-core",
@@ -303,12 +312,6 @@ dependencies = [
"slab",
]
[[package]]
name = "gcc"
version = "0.3.55"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8f5f3913fa0bfe7ee1fd8248b6b9f42a5af4b9d65ec2dd2c3c26132b950ecfc2"
[[package]]
name = "gdk-pixbuf"
version = "0.14.0"
@@ -331,14 +334,14 @@ dependencies = [
"glib-sys",
"gobject-sys",
"libc",
"system-deps",
"system-deps 3.2.0",
]
[[package]]
name = "gdk4"
version = "0.2.0"
version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8ce41092cc569129a0afa34926e6dd1cf8411e25652d87febdea36859f7ff7ba"
checksum = "4c0f7f98ad25b81ac9462f74a091b0e4c0983ed1e74d19a38230c772b4dcef81"
dependencies = [
"bitflags",
"cairo-rs",
@@ -352,9 +355,9 @@ dependencies = [
[[package]]
name = "gdk4-sys"
version = "0.2.0"
version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ce39c71861b5bcde319fd4711a74e1bd6f4f474911170d51096597fef0b56011"
checksum = "262a79666b42e1884577f11a050439a964b95dec55343ac6ace7930e1415fa18"
dependencies = [
"cairo-sys-rs",
"gdk-pixbuf-sys",
@@ -364,14 +367,14 @@ dependencies = [
"graphene-sys",
"libc",
"pango-sys",
"system-deps",
"system-deps 4.0.0",
]
[[package]]
name = "gio"
version = "0.14.0"
version = "0.14.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "86c6823b39d46d22cac2466de261f28d7f049ebc18f7b35296a42c7ed8a88325"
checksum = "f3a29d8062af72045518271a2cd98b4e1617ce43f5b4223ad0fb9a0eff8f718c"
dependencies = [
"bitflags",
"futures-channel",
@@ -393,15 +396,15 @@ dependencies = [
"glib-sys",
"gobject-sys",
"libc",
"system-deps",
"system-deps 3.2.0",
"winapi",
]
[[package]]
name = "glib"
version = "0.14.2"
version = "0.14.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dbecad7a3a898ee749d491ce2ae0decb0bce9e736f9747bc49159b1cea5d37f4"
checksum = "d4a930b7208e6e0ab839eea5f65ac2b82109f729621430d47fe905e2e09d33f4"
dependencies = [
"bitflags",
"futures-channel",
@@ -438,7 +441,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1c1d60554a212445e2a858e42a0e48cece1bd57b311a19a9468f70376cf554ae"
dependencies = [
"libc",
"system-deps",
"system-deps 3.2.0",
]
[[package]]
@@ -455,7 +458,7 @@ checksum = "aa92cae29759dae34ab5921d73fff5ad54b3d794ab842c117e36cafc7994c3f5"
dependencies = [
"glib-sys",
"libc",
"system-deps",
"system-deps 3.2.0",
]
[[package]]
@@ -478,14 +481,14 @@ dependencies = [
"glib-sys",
"libc",
"pkg-config",
"system-deps",
"system-deps 3.2.0",
]
[[package]]
name = "gsk4"
version = "0.2.0"
version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "64932b730eaad3340378a03d633616eeed6d6705b59b81c9f579c88be8932475"
checksum = "20b71f2e2cc699c2e0fbfa22899eeaffd84f9c1dc01e9263deac8664eec22dc0"
dependencies = [
"bitflags",
"cairo-rs",
@@ -499,9 +502,9 @@ dependencies = [
[[package]]
name = "gsk4-sys"
version = "0.2.0"
version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "685ffc776bedd91d68f47b41239525778b669432889721d7050d045270549b9a"
checksum = "30468aff80e4faadf22f9ba164ea17511a69a9995d7a13827a13424ef47b2472"
dependencies = [
"cairo-sys-rs",
"gdk4-sys",
@@ -510,14 +513,14 @@ dependencies = [
"graphene-sys",
"libc",
"pango-sys",
"system-deps",
"system-deps 4.0.0",
]
[[package]]
name = "gtk4"
version = "0.2.0"
version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c49e0311dac847a8ebc05e31f5c44c596314ee3b16c5f638ccfe24086d24bf1b"
checksum = "906f9308d15789d96a736881582181d710ae0937197119df459f3d2b46ef6776"
dependencies = [
"bitflags",
"cairo-rs",
@@ -538,9 +541,9 @@ dependencies = [
[[package]]
name = "gtk4-macros"
version = "0.2.0"
version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bbe4b77996bcf1ef20208c00043edda854ca2091b4be5e6a7c367f0f3846fa67"
checksum = "4d0d008cdf23214c697482415dd20f666bdf3cc9f5e803b017223c17c5b59a6e"
dependencies = [
"anyhow",
"heck",
@@ -554,9 +557,9 @@ dependencies = [
[[package]]
name = "gtk4-sys"
version = "0.2.0"
version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3737e91619cf4257d8a07834f7a2c035d4daeaf9ad8e3958e56b2c411dbdca18"
checksum = "d06be0a6322aa77dd372f726e97efbcbb192d9a824a414a8874f238effd7747c"
dependencies = [
"cairo-sys-rs",
"gdk-pixbuf-sys",
@@ -568,7 +571,7 @@ dependencies = [
"gsk4-sys",
"libc",
"pango-sys",
"system-deps",
"system-deps 4.0.0",
]
[[package]]
@@ -582,7 +585,7 @@ dependencies = [
[[package]]
name = "helvum"
version = "0.3.0"
version = "0.3.2"
dependencies = [
"env_logger 0.9.0",
"gtk4",
@@ -642,9 +645,9 @@ dependencies = [
[[package]]
name = "libc"
version = "0.2.98"
version = "0.2.103"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "320cfe77175da3a483efed4bc0adc1968ca050b098ce4f2f1c13a56626128790"
checksum = "dd8f7255a17a627354f321ef0055d63b898c6fb27eff628af4d1b66b7331edf6"
[[package]]
name = "libloading"
@@ -669,7 +672,7 @@ dependencies = [
"libc",
"libspa-sys",
"nom",
"system-deps",
"system-deps 3.2.0",
]
[[package]]
@@ -679,7 +682,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d301a2fc2fed0a97c13836408a4d98f419af0c2695ecf74e634a214c17beefa6"
dependencies = [
"bindgen",
"system-deps",
"system-deps 3.2.0",
]
[[package]]
@@ -740,9 +743,9 @@ checksum = "692fcb63b64b1758029e0a96ee63e049ce8c5948587f2f7208df04625e5f6b56"
[[package]]
name = "pango"
version = "0.14.0"
version = "0.14.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "415823a4fb9f1789785cd6e2d2413816f2ecff92380382969aaca9c400e13a19"
checksum = "e1fc88307d9797976ea62722ff2ec5de3fae279c6e20100ed3f49ca1a4bf3f96"
dependencies = [
"bitflags",
"glib",
@@ -760,7 +763,7 @@ dependencies = [
"glib-sys",
"gobject-sys",
"libc",
"system-deps",
"system-deps 3.2.0",
]
[[package]]
@@ -816,20 +819,20 @@ checksum = "9b4aa5ef9f3afef7dbb335106f69bd6bb541259e8796c693810cde20db1eb949"
dependencies = [
"bindgen",
"libspa-sys",
"system-deps",
"system-deps 3.2.0",
]
[[package]]
name = "pkg-config"
version = "0.3.19"
version = "0.3.20"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3831453b3449ceb48b6d9c7ad7c96d5ea673e9b470a1dc578c2ce6521230884c"
checksum = "7c9b1041b4387893b91ee6746cddfc28516aff326a3519fb2adf820932c5e6cb"
[[package]]
name = "proc-macro-crate"
version = "1.0.0"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "41fdbd1df62156fbc5945f4762632564d7d038153091c3fcf1067f6aef7cff92"
checksum = "1ebace6889caf889b4d3f76becee12e90353f2b8c7d875534a71e5742f8f6f83"
dependencies = [
"thiserror",
"toml",
@@ -861,9 +864,9 @@ dependencies = [
[[package]]
name = "proc-macro2"
version = "1.0.28"
version = "1.0.29"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5c7ed8b8c7b886ea3ed7dde405212185f423ab44682667c8c6dd14aa1d9f6612"
checksum = "b9f5105d4fdaab20335ca9565e106a5d9b82b6219b5ba735731124ac6711d23d"
dependencies = [
"unicode-xid",
]
@@ -941,15 +944,15 @@ dependencies = [
[[package]]
name = "serde"
version = "1.0.127"
version = "1.0.130"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f03b9878abf6d14e6779d3f24f07b2cfa90352cfec4acc5aab8f1ac7f146fae8"
checksum = "f12d06de37cf59146fbdecab66aa99f9fe4f78722e3607577a5375d66bd0c913"
[[package]]
name = "shlex"
version = "1.0.0"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "42a568c8f2cd051a4d283bd6eb0343ac214c1b0f1ac19f93e1175b2dee38c73d"
checksum = "43b2853a4d09f215c24cc5489c992ce46052d359b5109343cbafbf26bc62f8a3"
[[package]]
name = "signal"
@@ -969,9 +972,9 @@ checksum = "c307a32c1c5c437f38c7fd45d753050587732ba8628319fbdf12a7e289ccc590"
[[package]]
name = "smallvec"
version = "1.6.1"
version = "1.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fe0f37c9e8f3c5a4a66ad655a93c74daac4ad00c441533bf5c6e7990bb42604e"
checksum = "1ecab6c735a6bb4139c0caafd0cc3635748bbb3acf4550e8138122099251f309"
[[package]]
name = "static_assertions"
@@ -1005,9 +1008,9 @@ dependencies = [
[[package]]
name = "syn"
version = "1.0.74"
version = "1.0.77"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1873d832550d4588c3dbc20f01361ab00bfe741048f71e3fecf145a7cc18b29c"
checksum = "5239bc68e0fef57495900cfea4e8dc75596d9a319d7e16b1e0a440d24e6fe0a0"
dependencies = [
"proc-macro2",
"quote",
@@ -1021,7 +1024,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "480c269f870722b3b08d2f13053ce0c2ab722839f472863c3e2d61ff3a1c2fa6"
dependencies = [
"anyhow",
"cfg-expr",
"cfg-expr 0.8.1",
"heck",
"itertools",
"pkg-config",
@@ -1032,6 +1035,19 @@ dependencies = [
"version-compare",
]
[[package]]
name = "system-deps"
version = "4.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6c1889ab44c2a423ba9ba4d64cd04989b25c0280ca7ade813f05368418722a04"
dependencies = [
"cfg-expr 0.9.0",
"heck",
"pkg-config",
"toml",
"version-compare",
]
[[package]]
name = "tap"
version = "1.0.1"
@@ -1058,18 +1074,18 @@ dependencies = [
[[package]]
name = "thiserror"
version = "1.0.26"
version = "1.0.29"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "93119e4feac1cbe6c798c34d3a53ea0026b0b1de6a120deef895137c0529bfe2"
checksum = "602eca064b2d83369e2b2f34b09c70b605402801927c65c11071ac911d299b88"
dependencies = [
"thiserror-impl",
]
[[package]]
name = "thiserror-impl"
version = "1.0.26"
version = "1.0.29"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "060d69a0afe7796bf42e9e2ff91f5ee691fb15c53d38b4b62a9a53eb23164745"
checksum = "bad553cc2c78e8de258400763a647e80e6d1b31ee237275d756f6836d204494c"
dependencies = [
"proc-macro2",
"quote",
@@ -1099,9 +1115,9 @@ checksum = "8895849a949e7845e06bd6dc1aa51731a103c42707010a5b591c0038fb73385b"
[[package]]
name = "unicode-width"
version = "0.1.8"
version = "0.1.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9337591893a19b88d8d87f2cec1e73fad5cdfd10e5a6f349f498ad6ea2ffb1e3"
checksum = "3ed742d4ea2bd1176e236172c8429aaf54486e7ac098db29ffe6529e0ce50973"
[[package]]
name = "unicode-xid"

View File

@@ -1,8 +1,9 @@
[package]
name = "helvum"
version = "0.3.0"
version = "0.3.2"
authors = ["Tom A. Wagner <tom.a.wagner@protonmail.com>"]
edition = "2018"
edition = "2021"
rust-version = "1.56"
license = "GPL-3.0-only"
description = "A GTK patchbay for pipewire"
repository = "https://gitlab.freedesktop.org/ryuukyu/helvum"
@@ -14,7 +15,7 @@ categories = ["gui", "multimedia"]
[dependencies]
pipewire = "0.4"
gtk = { version = "0.2", package = "gtk4" }
gtk = { version = "0.3", package = "gtk4" }
log = "0.4.11"
env_logger = "0.9.0"

14
LICENSE
View File

@@ -1,7 +1,7 @@
GNU GENERAL PUBLIC LICENSE
Version 3, 29 June 2007
Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
Copyright (C) 2007 Free Software Foundation, Inc. <https://fsf.org/>
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
@@ -631,8 +631,8 @@ to attach them to the start of each source file to most effectively
state the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.
Helvum
Copyright (C) 2020 Ryuukyu
<one line to give the program's name and a brief idea of what it does.>
Copyright (C) <year> <name of author>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -645,14 +645,14 @@ the "copyright" line and a pointer to where the full notice is found.
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
along with this program. If not, see <https://www.gnu.org/licenses/>.
Also add information on how to contact you by electronic and paper mail.
If the program does terminal interaction, make it output a short
notice like this when it starts in an interactive mode:
Helvum Copyright (C) 2020 Ryuukyu
<program> Copyright (C) <year> <name of author>
This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
This is free software, and you are welcome to redistribute it
under certain conditions; type `show c' for details.
@@ -664,11 +664,11 @@ might be different; for a GUI interface, you would use an "about box".
You should also get your employer (if you work as a programmer) or school,
if any, to sign a "copyright disclaimer" for the program, if necessary.
For more information on this, and how to apply and follow the GNU GPL, see
<http://www.gnu.org/licenses/>.
<https://www.gnu.org/licenses/>.
The GNU General Public License does not permit incorporating your program
into proprietary programs. If your program is a subroutine library, you
may consider it more useful to permit linking proprietary applications with
the library. If this is what you want to do, use the GNU Lesser General
Public License instead of this License. But first, please read
<http://www.gnu.org/philosophy/why-not-lgpl.html>.
<https://www.gnu.org/licenses/why-not-lgpl.html>.

View File

@@ -1,6 +1,6 @@
Helvum is a GTK-based patchbay for pipewire, inspired by the JACK tool [catia](https://kx.studio/Applications:Catia).
![Screenshot](screenshot.png)
![Screenshot](docs/screenshot.png)
[![Packaging status](https://repology.org/badge/vertical-allrepos/helvum.svg)](https://repology.org/project/helvum/versions)
@@ -17,34 +17,44 @@ More suggestions are welcome!
## Via flatpak (recommended)
The recommended way to build is using flatpak, which will take care of all dependencies and avoid any problems that may come from different system configurations.
First, install the required flatpak platform and SDK, if you dont have them already:
If you don't have the flathub repo in your remote-list for flatpak you will need to add that first:
```shell
$ flatpak install org.gnome.{Platform,Sdk}//40 org.freedesktop.Sdk.Extension.rust-stable//20.08
$ flatpak remote-add --if-not-exists flathub https://flathub.org/repo/flathub.flatpakrepo
```
Then install the required flatpak platform and SDK, if you dont have them already:
```shell
$ flatpak install org.gnome.{Platform,Sdk}//41 org.freedesktop.Sdk.Extension.rust-stable//21.08 org.freedesktop.Sdk.Extension.llvm12//21.08
```
To compile and install as a flatpak, run
```shell
$ flatpak-builder --install flatpak-build/ org.freedesktop.ryuukyu.Helvum.json
$ flatpak-builder --install flatpak-build/ build-aux/org.freedesktop.ryuukyu.Helvum.json
```
You can then run the app via
```shell
flatpak run org.freedesktop.ryuukyu.Helvum
$ flatpak run org.freedesktop.ryuukyu.Helvum
```
## Manually
For compilation, you will need:
- Meson
- An up-to-date rust toolchain
- `libclang-3.7` or higher
- `gtk-4.0` and `pipewire-0.3` development headers
To compile, run
To compile and install, run
$ cargo build --release
```shell
$ meson setup build && cd build
$ meson compile
$ meson install
```
in the repository root.
The resulting binary will be at `target/release/helvum`.
This will install the compiled project files into `/usr/local`.
# License
Helvum is distributed under the terms of the GPL3 license.

21
build-aux/cargo.sh Executable file
View File

@@ -0,0 +1,21 @@
#!/usr/bin/env bash
set -euo pipefail
export MESON_BUILD_ROOT="$1"
export MESON_SOURCE_ROOT="$2"
export CARGO_TARGET_DIR="$MESON_BUILD_ROOT"/target
export CARGO_HOME="$MESON_BUILD_ROOT"/cargo-home
if [[ $4 = "development" ]]
then
echo "DEBUG MODE"
cargo build --manifest-path \
"$MESON_SOURCE_ROOT/Cargo.toml" && \
cp "$CARGO_TARGET_DIR/debug/$5" "$3"
else
echo "RELEASE MODE"
cargo build --manifest-path \
"$MESON_SOURCE_ROOT/Cargo.toml" --release && \
cp "$CARGO_TARGET_DIR/release/$5" "$3"
fi

12
build-aux/dist-vendor.sh Normal file
View File

@@ -0,0 +1,12 @@
#!/usr/bin/env bash
set -euo pipefail
export DIST="$1"
export SOURCE_ROOT="$2"
cd "$SOURCE_ROOT"
mkdir "$DIST"/.cargo
cargo vendor > $DIST/.cargo/config
# Move vendor into dist tarball directory
mv vendor "$DIST"

View File

@@ -0,0 +1,12 @@
#!/usr/bin/env python3
from os import environ, path
from subprocess import call
if not environ.get('DESTDIR', ''):
PREFIX = environ.get('MESON_INSTALL_PREFIX', '/usr/local')
DATA_DIR = path.join(PREFIX, 'share')
print('Updating icon cache...')
call(['gtk-update-icon-cache', '-qtf', path.join(DATA_DIR, 'icons/hicolor')])
print("Updating desktop database...")
call(["update-desktop-database", path.join(DATA_DIR, 'applications')])

View File

@@ -1,35 +1,39 @@
{
"app-id": "org.freedesktop.ryuukyu.Helvum",
"runtime": "org.gnome.Platform",
"runtime-version": "40",
"runtime-version": "41",
"sdk": "org.gnome.Sdk",
"sdk-extensions": ["org.freedesktop.Sdk.Extension.rust-stable"],
"sdk-extensions": [
"org.freedesktop.Sdk.Extension.rust-stable",
"org.freedesktop.Sdk.Extension.llvm12"
],
"command": "helvum",
"finish-args" : [
"finish-args": [
"--socket=fallback-x11",
"--socket=wayland",
"--device=dri",
"--share=ipc",
"--filesystem=xdg-run/pipewire-0"
],
"build-options" : {
"append-path" : "/usr/lib/sdk/rust-stable/bin",
"build-args" : [
"build-options": {
"append-path": "/usr/lib/sdk/rust-stable/bin:/usr/lib/sdk/llvm12/bin",
"prepend-ld-library-path": "/usr/lib/sdk/llvm12/lib",
"build-args": [
"--share=network"
]
},
"modules": [
{
"name": "Helvum",
"buildsystem": "simple",
"build-commands": [
"cargo install --path . --root /app --no-track"
],
"buildsystem": "meson",
"sources": [
{
"type": "dir",
"path": "./"
"path": "../"
}
],
"config-opts": [
"-Dprofile=development"
]
}
]

9
data/icons/meson.build Normal file
View File

@@ -0,0 +1,9 @@
install_data(
'@0@.svg'.format(base_id),
install_dir: iconsdir / 'hicolor' / 'scalable' / 'apps'
)
install_data(
'@0@-symbolic.svg'.format(base_id),
install_dir: iconsdir / 'hicolor' / 'symbolic' / 'apps',
)

View File

@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg height="16px" viewBox="0 0 16 16" width="16px" xmlns="http://www.w3.org/2000/svg">
<path d="m 3.5 2.5 h 9 c 1.378906 0 2.5 1.121094 2.5 2.5 v 5 c 0 1.378906 -1.121094 2.5 -2.5 2.5 h -9 c -1.378906 0 -2.5 -1.121094 -2.5 -2.5 v -5 c 0 -1.378906 1.121094 -2.5 2.5 -2.5 z m 0 0" fill="#241f31" fill-rule="evenodd"/>
<g fill="none" stroke="#8a8891">
<path d="m 11 7.5 h -6"/>
<path d="m 5 7.5 c 0 -4.15625 -1.382812 -10.855469 -3.90625 -13.25" stroke-linecap="round" stroke-linejoin="bevel" stroke-width="4"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 589 B

File diff suppressed because it is too large Load Diff

After

Width:  |  Height:  |  Size: 187 KiB

View File

@@ -0,0 +1,56 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg height="128px" viewBox="0 0 128 128" width="128px" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<linearGradient id="a" gradientUnits="userSpaceOnUse">
<stop offset="0" stop-color="#9a9996"/>
<stop offset="0.5" stop-color="#c0bfbc"/>
<stop offset="1" stop-color="#deddda"/>
</linearGradient>
<linearGradient id="b" x1="26.263471" x2="26.263586" xlink:href="#a" y1="24.848538" y2="37.1125"/>
<linearGradient id="c" gradientUnits="userSpaceOnUse" x1="7.39555839647" x2="120.60350567947" y1="82.86737386462" y2="82.86737386462">
<stop offset="0" stop-color="#5e5c64"/>
<stop offset="0.0384615" stop-color="#77767b"/>
<stop offset="0.0768555" stop-color="#5e5c64"/>
<stop offset="0.923077" stop-color="#5e5c64"/>
<stop offset="0.961538" stop-color="#77767b"/>
<stop offset="1" stop-color="#5e5c64"/>
</linearGradient>
<linearGradient id="d" gradientTransform="matrix(2.571428 0 0 2.454545 22.856596 -228.048061)" x1="16" x2="16" xlink:href="#a" y1="121.582512" y2="127.082512"/>
<linearGradient id="e" gradientTransform="matrix(2.571428 0 0 2.454545 22.856596 -253.563246)" x1="16" x2="16" xlink:href="#a" y1="121.582512" y2="127.082512"/>
<linearGradient id="f" gradientTransform="matrix(2.571428 0 0 2.454545 60.592569 -253.563246)" x1="16" x2="16" xlink:href="#a" y1="121.582512" y2="127.082512"/>
<linearGradient id="g" gradientTransform="matrix(2.571428 0 0 2.454545 60.592569 -228.048061)" x1="16" x2="16" xlink:href="#a" y1="121.582512" y2="127.082512"/>
<linearGradient id="h" gradientTransform="matrix(2.358499 0 0 2.251294 -11.472502 -204.652927)" gradientUnits="userSpaceOnUse" x1="12.5" x2="19.5" y1="113.832512" y2="113.832512">
<stop offset="0" stop-color="#c0bfbc"/>
<stop offset="0.5" stop-color="#9a9996"/>
<stop offset="1" stop-color="#c0bfbc"/>
</linearGradient>
<linearGradient id="i" gradientTransform="matrix(2.571428 0 0 2.454545 -14.879853 -228.048061)" x1="16" x2="16" xlink:href="#a" y1="121.582512" y2="127.082512"/>
<path d="m 34.519531 30.980469 c 0 3.386719 -3.695312 6.132812 -8.257812 6.132812 c -4.558594 0 -8.253907 -2.746093 -8.253907 -6.132812 s 3.695313 -6.132813 8.253907 -6.132813 c 4.5625 0 8.257812 2.746094 8.257812 6.132813 z m 0 0" fill="url(#b)" fill-rule="evenodd"/>
<path d="m 120.601562 82.867188 v 18.867187 c 0 5.226563 -4.207031 9.433594 -9.433593 9.433594 h -94.339844 c -5.226563 0 -9.433594 -4.207031 -9.433594 -9.433594 v -18.867187 z m 0 0" fill="url(#c)" fill-rule="evenodd"/>
<path d="m 16.828125 35.699219 c -5.226563 0 -9.433594 4.207031 -9.433594 9.433593 v 37.734376 c 0 5.226562 4.207031 9.433593 9.433594 9.433593 h 94.339844 c 5.226562 0 9.4375 -4.207031 9.4375 -9.433593 v -37.734376 c 0 -5.226562 -4.210938 -9.433593 -9.4375 -9.433593 h -76.648438 v 2.355469 h -16.511719 v -2.355469 z m 0 0" fill="#77767b" fill-rule="evenodd"/>
<path d="m 93.480469 76.378906 l -30.660157 -24.761718" fill="none" stroke="#77767b" stroke-linecap="square" stroke-width="3.74412"/>
<path d="m 64 58.691406 v 10.613282" fill="none" stroke="#999999" stroke-width="1.5"/>
<g fill-rule="evenodd">
<path d="m 75 77.132812 c 0 4.554688 -4.925781 8.25 -11 8.25 s -11 -3.695312 -11 -8.25 c 0 -4.558593 4.925781 -8.25 11 -8.25 s 11 3.691407 11 8.25 z m 0 0" fill="#e01b24"/>
<path d="m 73 77.132812 c 0 3.726563 -4.03125 6.75 -9 6.75 c -4.972656 0 -9 -3.023437 -9 -6.75 c 0 -3.730468 4.027344 -6.75 9 -6.75 c 4.96875 0 9 3.019532 9 6.75 z m 0 0" fill="url(#d)"/>
<path d="m 71 77.132812 c 0 2.898438 -3.132812 5.25 -7 5.25 s -7 -2.351562 -7 -5.25 c 0 -2.902343 3.132812 -5.25 7 -5.25 s 7 2.347657 7 5.25 z m 0 0" fill="#3d3846"/>
<path d="m 75 51.617188 c 0 4.554687 -4.925781 8.25 -11 8.25 s -11 -3.695313 -11 -8.25 c 0 -4.558594 4.925781 -8.25 11 -8.25 s 11 3.691406 11 8.25 z m 0 0" fill="#1c71d8"/>
<path d="m 73 51.617188 c 0 3.726562 -4.03125 6.75 -9 6.75 c -4.972656 0 -9 -3.023438 -9 -6.75 c 0 -3.730469 4.027344 -6.75 9 -6.75 c 4.96875 0 9 3.019531 9 6.75 z m 0 0" fill="url(#e)"/>
<path d="m 71 51.617188 c 0 2.898437 -3.132812 5.25 -7 5.25 s -7 -2.351563 -7 -5.25 c 0 -2.898438 3.132812 -5.25 7 -5.25 s 7 2.351562 7 5.25 z m 0 0" fill="#3d3846"/>
<path d="m 112.734375 51.617188 c 0 4.554687 -4.921875 8.25 -11 8.25 c -6.074219 0 -11 -3.695313 -11 -8.25 c 0 -4.558594 4.925781 -8.25 11 -8.25 c 6.078125 0 11 3.691406 11 8.25 z m 0 0" fill="#1c71d8"/>
<path d="m 110.734375 51.617188 c 0 3.726562 -4.027344 6.75 -9 6.75 c -4.96875 0 -9 -3.023438 -9 -6.75 c 0 -3.730469 4.03125 -6.75 9 -6.75 c 4.972656 0 9 3.019531 9 6.75 z m 0 0" fill="url(#f)"/>
<path d="m 108.734375 51.617188 c 0 2.898437 -3.132813 5.25 -7 5.25 c -3.863281 0 -7 -2.351563 -7 -5.25 c 0 -2.898438 3.136719 -5.25 7 -5.25 c 3.867187 0 7 2.351562 7 5.25 z m 0 0" fill="#3d3846"/>
</g>
<path d="m 101.734375 58.691406 v 10.613282" fill="none" stroke="#999999" stroke-width="1.5"/>
<path d="m 112.734375 77.132812 c 0 4.554688 -4.921875 8.25 -11 8.25 c -6.074219 0 -11 -3.695312 -11 -8.25 c 0 -4.558593 4.925781 -8.25 11 -8.25 c 6.078125 0 11 3.691407 11 8.25 z m 0 0" fill="#e01b24" fill-rule="evenodd"/>
<path d="m 110.734375 77.132812 c 0 3.726563 -4.027344 6.75 -9 6.75 c -4.96875 0 -9 -3.023437 -9 -6.75 c 0 -3.730468 4.03125 -6.75 9 -6.75 c 4.972656 0 9 3.019532 9 6.75 z m 0 0" fill="url(#g)" fill-rule="evenodd"/>
<path d="m 108.734375 77.132812 c 0 2.898438 -3.132813 5.25 -7 5.25 c -3.863281 0 -7 -2.351562 -7 -5.25 c 0 -2.902343 3.136719 -5.25 7 -5.25 c 3.867187 0 7 2.347657 7 5.25 z m 0 0" fill="#3d3846" fill-rule="evenodd"/>
<path d="m 26.261719 69.339844 v -10.648438" fill="none" stroke="#999999" stroke-width="1.5"/>
<path d="m 37.261719 52.515625 c 0 4.238281 -4.921875 7.671875 -11 7.671875 c -6.074219 0 -11 -3.433594 -11 -7.671875 c 0 -4.234375 4.925781 -7.671875 11 -7.671875 c 6.078125 0 11 3.4375 11 7.671875 z m 0 0" fill="#1c71d8" fill-rule="evenodd"/>
<path d="m 18.007812 30.980469 v 20.636719 c 0.003907 3.417968 3.699219 6.191406 8.253907 6.191406 c 4.554687 0 8.25 -2.765625 8.253906 -6.183594 c 0 0 0 -0.003906 0 -0.007812 v -20.636719 c -1.308594 2.597656 -4.589844 6.132812 -8.253906 6.132812 c -3.660157 0 -6.941407 -3.535156 -8.253907 -6.132812 z m 0 0" fill="url(#h)" fill-rule="evenodd"/>
<path d="m 37.261719 77.132812 c 0 4.554688 -4.921875 8.25 -11 8.25 c -6.074219 0 -11 -3.695312 -11 -8.25 c 0 -4.558593 4.925781 -8.25 11 -8.25 c 6.078125 0 11 3.691407 11 8.25 z m 0 0" fill="#e01b24" fill-rule="evenodd"/>
<path d="m 35.261719 77.132812 c 0 3.726563 -4.027344 6.75 -9 6.75 c -4.96875 0 -9 -3.023437 -9 -6.75 c 0 -3.730468 4.03125 -6.75 9 -6.75 c 4.972656 0 9 3.019532 9 6.75 z m 0 0" fill="url(#i)" fill-rule="evenodd"/>
<path d="m 33.261719 77.132812 c 0 2.898438 -3.132813 5.25 -7 5.25 c -3.863281 0 -7 -2.351562 -7 -5.25 c 0 -2.902343 3.136719 -5.25 7 -5.25 c 3.867187 0 7 2.347657 7 5.25 z m 0 0" fill="#3d3846" fill-rule="evenodd"/>
<path d="m 34.519531 30.980469 c 0 3.386719 -3.695312 6.132812 -8.257812 6.132812 c -4.558594 0 -8.253907 -2.746093 -8.253907 -6.132812 s 3.695313 -6.132813 8.253907 -6.132813 c 4.5625 0 8.257812 2.746094 8.257812 6.132813 z m 0 0" fill="#c0bfbc" fill-rule="evenodd"/>
<path d="m 30.980469 30.980469 c 0 1.953125 -2.113281 3.539062 -4.71875 3.539062 c -2.601563 0 -4.714844 -1.585937 -4.714844 -3.539062 s 2.113281 -3.539063 4.714844 -3.539063 c 2.605469 0 4.71875 1.585938 4.71875 3.539063 z m 0 0" fill="#1a5fb4" fill-rule="evenodd"/>
<path d="m 26.261719 30.980469 c 0 -7.074219 0.628906 -18.371094 -10.285157 -21.847657 c -11.828124 -3.765624 -33.882812 3 -33.882812 3" fill="none" stroke="#1a5fb4" stroke-width="9.434"/>
</svg>

After

Width:  |  Height:  |  Size: 7.7 KiB

24
data/meson.build Normal file
View File

@@ -0,0 +1,24 @@
subdir('icons')
desktop_conf = configuration_data()
desktop_conf.set('icon', base_id)
desktop_file = configure_file(
input: '@0@.desktop.in'.format(base_id),
output: '@BASENAME@',
configuration: desktop_conf
)
if desktop_file_validate.found()
test(
'validate-desktop',
desktop_file_validate,
args: [
desktop_file
],
)
endif
install_data(
desktop_file,
install_dir: datadir / 'applications'
)

View File

@@ -0,0 +1,9 @@
[Desktop Entry]
Name=Helvum
GenericName=Patchbay
Comment=A patchbay for pipewire
Type=Application
Exec=helvum
Terminal=false
Categories=AudioVideo;Audio;Video;Midi;Settings;GNOME;GTK;
Icon=@icon@

BIN
docs/screenshot.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 65 KiB

38
meson.build Normal file
View File

@@ -0,0 +1,38 @@
project(
'helvum',
'rust',
version: '0.3.2',
license: 'GPL-3.0',
meson_version: '>=0.50.0'
)
base_id = 'org.freedesktop.ryuukyu.Helvum'
dependency('glib-2.0', version: '>= 2.48')
dependency('gtk4', version: '>= 4.4.0')
dependency('libpipewire-0.3')
desktop_file_validate = find_program('desktop-file-validate', required: false)
cargo = find_program('cargo', required: true)
cargo_script = find_program('build-aux/cargo.sh')
prefix = get_option('prefix')
bindir = prefix / get_option('bindir')
datadir = prefix / get_option('datadir')
iconsdir = datadir / 'icons'
meson.add_dist_script(
'build-aux/dist-vendor.sh',
meson.build_root() / 'meson-dist' / meson.project_name() + '-' + meson.project_version(),
meson.source_root()
)
cargo_sources = files(
'Cargo.toml',
'Cargo.lock',
)
subdir('src')
subdir('data')
meson.add_install_script('build-aux/meson_post_install.py')

11
meson_options.txt Normal file
View File

@@ -0,0 +1,11 @@
option(
'profile',
type: 'combo',
choices: [
'default',
'development'
],
value: 'default',
description: 'The build profile for Helvum. One of "default" or "development".'
)

Binary file not shown.

Before

Width:  |  Height:  |  Size: 53 KiB

View File

@@ -1,3 +1,22 @@
// application.rs
//
// Copyright 2021 Tom A. Wagner <tom.a.wagner@protonmail.com>
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
//
// SPDX-License-Identifier: GPL-3.0-only
use std::cell::RefCell;
use gtk::{
@@ -11,7 +30,7 @@ use pipewire::{channel::Sender, spa::Direction};
use crate::{
view::{self},
GtkMessage, MediaType, PipewireLink, PipewireMessage,
GtkMessage, MediaType, NodeType, PipewireLink, PipewireMessage,
};
static STYLE: &str = include_str!("style.css");
@@ -108,7 +127,7 @@ impl Application {
@weak app => @default-return Continue(true),
move |msg| {
match msg {
PipewireMessage::NodeAdded{ id, name } => app.add_node(id, name.as_str()),
PipewireMessage::NodeAdded{ id, name, node_type } => app.add_node(id, name.as_str(), node_type),
PipewireMessage::PortAdded{ id, node_id, name, direction, media_type } => app.add_port(id, name.as_str(), node_id, direction, media_type),
PipewireMessage::LinkAdded{ id, node_from, port_from, node_to, port_to, active} => app.add_link(id, node_from, port_from, node_to, port_to, active),
PipewireMessage::LinkStateChanged { id, active } => app.link_state_changed(id, active), // TODO
@@ -125,12 +144,14 @@ impl Application {
}
/// Add a new node to the view.
fn add_node(&self, id: u32, name: &str) {
fn add_node(&self, id: u32, name: &str, node_type: Option<NodeType>) {
info!("Adding node to graph: id {}", id);
imp::Application::from_instance(self)
.graphview
.add_node(id, view::Node::new(name));
imp::Application::from_instance(self).graphview.add_node(
id,
view::Node::new(name),
node_type,
);
}
/// Add a new port to the view.

View File

@@ -1,3 +1,22 @@
// main.rs
//
// Copyright 2021 Tom A. Wagner <tom.a.wagner@protonmail.com>
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
//
// SPDX-License-Identifier: GPL-3.0-only
mod application;
mod pipewire_connection;
mod view;
@@ -23,6 +42,7 @@ enum PipewireMessage {
NodeAdded {
id: u32,
name: String,
node_type: Option<NodeType>,
},
PortAdded {
id: u32,
@@ -55,6 +75,12 @@ enum PipewireMessage {
},
}
#[derive(Debug, Clone)]
pub enum NodeType {
Input,
Output,
}
#[derive(Debug, Copy, Clone)]
pub enum MediaType {
Audio,

32
src/meson.build Normal file
View File

@@ -0,0 +1,32 @@
rust_sources = files(
'application.rs',
'main.rs',
'pipewire_connection.rs',
'pipewire_connection/state.rs',
'style.css',
'view/graph_view.rs',
'view/mod.rs',
'view/node.rs',
'view/port.rs',
)
custom_target(
'cargo-build',
build_by_default: true,
input: [
cargo_sources,
rust_sources
],
output: meson.project_name(),
console: true,
install: true,
install_dir: bindir,
command: [
cargo_script,
meson.build_root(),
meson.source_root(),
'@OUTPUT@',
get_option('profile'),
meson.project_name(),
],
)

View File

@@ -1,3 +1,22 @@
// pipewire_connection.rs
//
// Copyright 2021 Tom A. Wagner <tom.a.wagner@protonmail.com>
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
//
// SPDX-License-Identifier: GPL-3.0-only
mod state;
use std::{cell::RefCell, collections::HashMap, rc::Rc};
@@ -14,7 +33,7 @@ use pipewire::{
Context, Core, MainLoop,
};
use crate::{GtkMessage, MediaType, PipewireMessage};
use crate::{GtkMessage, MediaType, NodeType, PipewireMessage};
use state::{Item, State};
enum ProxyItem {
@@ -112,6 +131,27 @@ fn handle_node(
}
});
let media_class = |class: &str| {
if class.contains("Sink") || class.contains("Input") {
Some(NodeType::Input)
} else if class.contains("Source") || class.contains("Output") {
Some(NodeType::Output)
} else {
None
}
};
let node_type = props
.get("media.category")
.and_then(|class| {
if class.contains("Duplex") {
None
} else {
props.get("media.class").and_then(media_class)
}
})
.or_else(|| props.get("media.class").and_then(media_class));
state.borrow_mut().insert(
node.id,
Item::Node {
@@ -121,7 +161,11 @@ fn handle_node(
);
sender
.send(PipewireMessage::NodeAdded { id: node.id, name })
.send(PipewireMessage::NodeAdded {
id: node.id,
name,
node_type,
})
.expect("Failed to send message");
}

View File

@@ -1,3 +1,22 @@
// state.rs
//
// Copyright 2021 Tom A. Wagner <tom.a.wagner@protonmail.com>
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
//
// SPDX-License-Identifier: GPL-3.0-only
use std::collections::HashMap;
use crate::MediaType;

View File

@@ -1,14 +1,23 @@
@define-color audio rgb(50,100,240);
@define-color video rgb(200,200,0);
@define-color midi rgb(200,0,50);
@define-color graphview-link #808080;
.audio {
background: rgb(50,100,240);
background: @audio;
color: black;
}
.video {
background: rgb(200,200,0);
background: @video;
color: black;
}
.midi {
background: rgb(200,0,50);
background: @midi;
color: black;
}
graphview {
background: @text_view_bg;
}

View File

@@ -1,3 +1,22 @@
// graph_view.rs
//
// Copyright 2021 Tom A. Wagner <tom.a.wagner@protonmail.com>
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
//
// SPDX-License-Identifier: GPL-3.0-only
use super::{Node, Port};
use gtk::{
@@ -8,7 +27,9 @@ use gtk::{
};
use log::{error, warn};
use std::collections::HashMap;
use std::{cmp::Ordering, collections::HashMap};
use crate::NodeType;
mod imp {
use super::*;
@@ -33,6 +54,7 @@ mod imp {
fn class_init(klass: &mut Self::Class) {
// The layout manager determines how child widgets are laid out.
klass.set_layout_manager_type::<gtk::FixedLayout>();
klass.set_css_name("graphview");
}
}
@@ -45,27 +67,32 @@ mod imp {
drag_controller.connect_drag_begin(
clone!(@strong drag_state => move |drag_controller, x, y| {
let mut drag_state = drag_state.borrow_mut();
let widget = drag_controller
.widget()
.expect("drag-begin event has no widget")
.dynamic_cast::<Self::Type>()
.expect("drag-begin event is not on the GraphView");
// pick() should at least return the widget itself.
let target = widget.pick(x, y, gtk::PickFlags::DEFAULT).expect("drag-begin pick() did not return a widget");
*drag_state = if target.ancestor(Port::static_type()).is_some() {
// The user targeted a port, so the dragging should be handled by the Port
// component instead of here.
None
} else if let Some(target) = target.ancestor(Node::static_type()) {
// The user targeted a Node without targeting a specific Port.
// Drag the Node around the screen.
let (x, y) = widget.get_node_position(&target);
Some((target, x, y))
} else {
None
let mut drag_state = drag_state.borrow_mut();
let widget = drag_controller
.widget()
.expect("drag-begin event has no widget")
.dynamic_cast::<Self::Type>()
.expect("drag-begin event is not on the GraphView");
// pick() should at least return the widget itself.
let target = widget.pick(x, y, gtk::PickFlags::DEFAULT).expect("drag-begin pick() did not return a widget");
*drag_state = if target.ancestor(Port::static_type()).is_some() {
// The user targeted a port, so the dragging should be handled by the Port
// component instead of here.
None
} else if let Some(target) = target.ancestor(Node::static_type()) {
// The user targeted a Node without targeting a specific Port.
// Drag the Node around the screen.
if let Some((x, y)) = widget.get_node_position(&target) {
Some((target, x, y))
} else {
error!("Failed to obtain position of dragged node, drag aborted.");
None
}
} else {
None
}
}
}));
));
drag_controller.connect_drag_update(
clone!(@strong drag_state => move |drag_controller, x, y| {
let widget = drag_controller
@@ -97,24 +124,13 @@ mod imp {
Try to use relative units (em) and colours from the theme as much as possible. */
let alloc = widget.allocation();
let widget_bounds =
graphene::Rect::new(0.0, 0.0, alloc.width as f32, alloc.height as f32);
let background_cr = snapshot
.append_cairo(&graphene::Rect::new(
0.0,
0.0,
alloc.width as f32,
alloc.height as f32,
))
.append_cairo(&widget_bounds)
.expect("Failed to get cairo context");
// Try to replace the background color with a darker one from the theme.
if let Some(rgba) = widget.style_context().lookup_color("text_view_bg") {
background_cr.set_source_rgb(rgba.red.into(), rgba.green.into(), rgba.blue.into());
if let Err(e) = background_cr.paint() {
warn!("Failed to paint graphview background: {}", e);
};
} // TODO: else log colour not found
// Draw a nice grid on the background.
background_cr.set_source_rgb(0.18, 0.18, 0.18);
background_cr.set_line_width(0.2); // TODO: Set to 1px
@@ -149,8 +165,25 @@ mod imp {
alloc.height as f32,
))
.expect("Failed to get cairo context");
link_cr.set_line_width(2.0);
link_cr.set_source_rgb(0.0, 0.0, 0.0);
let gtk::gdk::RGBA {
red,
green,
blue,
alpha,
} = widget
.style_context()
.lookup_color("graphview-link")
.unwrap_or(gtk::gdk::RGBA {
red: 0.0,
green: 0.0,
blue: 0.0,
alpha: 0.0,
});
link_cr.set_source_rgba(red.into(), green.into(), blue.into(), alpha.into());
for (link, active) in self.links.borrow().values() {
if let Some((from_x, from_y, to_x, to_y)) = self.get_link_coordinates(link) {
link_cr.move_to(from_x, from_y);
@@ -162,15 +195,24 @@ mod imp {
link_cr.set_dash(&[10.0, 5.0], 0.0);
}
// If the output port is farther right than the input port and they have
// a similar y coordinate, apply a y offset to the control points
// so that the curve sticks out a bit.
let y_control_offset = if from_x > to_x {
f64::max(0.0, 25.0 - (from_y - to_y).abs())
} else {
0.0
};
// Place curve control offset by half the x distance between the two points.
// This makes the curve scale well for varying distances between the two ports,
// especially when the output port is farther right than the input port.
let half_x_dist = f64::abs(from_x - to_x) / 2.0;
link_cr.curve_to(
from_x + half_x_dist,
from_y,
from_y - y_control_offset,
to_x - half_x_dist,
to_y,
to_y - y_control_offset,
to_x,
to_y,
);
@@ -239,14 +281,37 @@ impl GraphView {
glib::Object::new(&[]).expect("Failed to create GraphView")
}
pub fn add_node(&self, id: u32, node: Node) {
pub fn add_node(&self, id: u32, node: Node, node_type: Option<NodeType>) {
let private = imp::GraphView::from_instance(self);
node.set_parent(self);
// Place widgets in colums of 4, growing down, then right.
// TODO: Make a better positioning algorithm.
let x = ((private.nodes.borrow().len() / 4) as f32 * 400.0) + 20.0; // This relies on integer division rounding down.
let y = (private.nodes.borrow().len() as f32 % 4.0 * 100.0) + 20.0;
// Place widgets in colums of 3, growing down
let x = if let Some(node_type) = node_type {
match node_type {
NodeType::Output => 20.0,
NodeType::Input => 820.0,
}
} else {
420.0
};
let y = private
.nodes
.borrow()
.values()
.filter_map(|node| {
// Map nodes to locations, discard nodes without location
self.get_node_position(&node.clone().upcast())
})
.filter(|(x2, _)| {
// Only look for other nodes that have a similar x coordinate
(x - x2).abs() < 50.0
})
.max_by(|y1, y2| {
// Get max in column
y1.partial_cmp(y2).unwrap_or(Ordering::Equal)
})
.map_or(20_f32, |(_x, y)| y + 100.0);
self.move_node(&node.clone().upcast(), x, y);
@@ -308,7 +373,10 @@ impl GraphView {
self.queue_draw();
}
pub(super) fn get_node_position(&self, node: &gtk::Widget) -> (f32, f32) {
/// Get the position of the specified node inside the graphview.
///
/// Returns `None` if the node is not in the graphview.
pub(super) fn get_node_position(&self, node: &gtk::Widget) -> Option<(f32, f32)> {
let layout_manager = self
.layout_manager()
.expect("Failed to get layout manager")
@@ -316,12 +384,13 @@ impl GraphView {
.expect("Failed to cast to FixedLayout");
let node = layout_manager
.layout_child(node)
.expect("Could not get layout child")
.layout_child(node)?
.dynamic_cast::<gtk::FixedLayoutChild>()
.expect("Could not cast to FixedLayoutChild");
let transform = node.transform().unwrap_or_default();
transform.to_translate()
let transform = node
.transform()
.expect("Failed to obtain transform from layout child");
Some(transform.to_translate())
}
pub(super) fn move_node(&self, node: &gtk::Widget, x: f32, y: f32) {

View File

@@ -1,3 +1,22 @@
// mod.rs
//
// Copyright 2021 Tom A. Wagner <tom.a.wagner@protonmail.com>
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
//
// SPDX-License-Identifier: GPL-3.0-only
//! The view presented to the user.
//!
//! This module contains gtk widgets needed to present the graphical user interface.

View File

@@ -1,3 +1,22 @@
// node.rs
//
// Copyright 2021 Tom A. Wagner <tom.a.wagner@protonmail.com>
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
//
// SPDX-License-Identifier: GPL-3.0-only
use gtk::{glib, prelude::*, subclass::prelude::*};
use pipewire::spa::Direction;

View File

@@ -1,3 +1,22 @@
// port.rs
//
// Copyright 2021 Tom A. Wagner <tom.a.wagner@protonmail.com>
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
//
// SPDX-License-Identifier: GPL-3.0-only
use gtk::{
gdk,
glib::{self, clone, subclass::Signal},