diff --git a/.editorconfig b/.editorconfig
deleted file mode 100644
index fddd70ad5..000000000
--- a/.editorconfig
+++ /dev/null
@@ -1,17 +0,0 @@
-root = true
-
-[*]
-end_of_line = lf
-indent_style = space
-trim_trailing_whitespace = true
-insert_final_newline = true
-charset = utf-8
-
-[*.{txt,build,json,xml,xml.in,in}]
-indent_size = 2
-
-[*.{vala,py}]
-indent_size = 4
-block_comment_start = /**
-block_comment = *
-block_comment_end = */
diff --git a/.gitignore b/.gitignore
index 172b03c3e..899182c02 100644
--- a/.gitignore
+++ b/.gitignore
@@ -7,3 +7,8 @@ _build/
build*/
.flatpak-builder/
*~
+
+
+# Added by cargo
+
+/target
diff --git a/Cargo.lock b/Cargo.lock
new file mode 100644
index 000000000..a7dd1278e
--- /dev/null
+++ b/Cargo.lock
@@ -0,0 +1,915 @@
+# This file is automatically @generated by Cargo.
+# It is not intended for manual editing.
+version = 3
+
+[[package]]
+name = "aho-corasick"
+version = "1.1.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916"
+dependencies = [
+ "memchr",
+]
+
+[[package]]
+name = "akira"
+version = "0.1.0"
+dependencies = [
+ "gettext-rs",
+ "granite-rs",
+ "gtk4",
+ "once_cell",
+]
+
+[[package]]
+name = "autocfg"
+version = "1.3.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0"
+
+[[package]]
+name = "bitflags"
+version = "2.6.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de"
+
+[[package]]
+name = "block"
+version = "0.1.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0d8c1fef690941d3e7788d328517591fecc684c084084702d6ff1641e993699a"
+
+[[package]]
+name = "cairo-rs"
+version = "0.20.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e8a0ea147c94108c9613235388f540e4d14c327f7081c9e471fc8ee8a2533e69"
+dependencies = [
+ "bitflags",
+ "cairo-sys-rs",
+ "glib",
+ "libc",
+]
+
+[[package]]
+name = "cairo-sys-rs"
+version = "0.20.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "428290f914b9b86089f60f5d8a9f6e440508e1bcff23b25afd51502b0a2da88f"
+dependencies = [
+ "glib-sys",
+ "libc",
+ "system-deps",
+]
+
+[[package]]
+name = "cc"
+version = "1.1.19"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2d74707dde2ba56f86ae90effb3b43ddd369504387e718014de010cec7959800"
+dependencies = [
+ "shlex",
+]
+
+[[package]]
+name = "cfg-expr"
+version = "0.16.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "345c78335be0624ed29012dc10c49102196c6882c12dde65d9f35b02da2aada8"
+dependencies = [
+ "smallvec",
+ "target-lexicon",
+]
+
+[[package]]
+name = "equivalent"
+version = "1.0.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5"
+
+[[package]]
+name = "field-offset"
+version = "0.3.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "38e2275cc4e4fc009b0669731a1e5ab7ebf11f469eaede2bab9309a5b4d6057f"
+dependencies = [
+ "memoffset",
+ "rustc_version",
+]
+
+[[package]]
+name = "futures-channel"
+version = "0.3.30"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "eac8f7d7865dcb88bd4373ab671c8cf4508703796caa2b1985a9ca867b3fcb78"
+dependencies = [
+ "futures-core",
+]
+
+[[package]]
+name = "futures-core"
+version = "0.3.30"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "dfc6580bb841c5a68e9ef15c77ccc837b40a7504914d52e47b8b0e9bbda25a1d"
+
+[[package]]
+name = "futures-executor"
+version = "0.3.30"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a576fc72ae164fca6b9db127eaa9a9dda0d61316034f33a0a0d4eda41f02b01d"
+dependencies = [
+ "futures-core",
+ "futures-task",
+ "futures-util",
+]
+
+[[package]]
+name = "futures-io"
+version = "0.3.30"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a44623e20b9681a318efdd71c299b6b222ed6f231972bfe2f224ebad6311f0c1"
+
+[[package]]
+name = "futures-macro"
+version = "0.3.30"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "87750cf4b7a4c0625b1529e4c543c2182106e4dedc60a2a6455e00d212c489ac"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn",
+]
+
+[[package]]
+name = "futures-task"
+version = "0.3.30"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "38d84fa142264698cdce1a9f9172cf383a0c82de1bddcf3092901442c4097004"
+
+[[package]]
+name = "futures-util"
+version = "0.3.30"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3d6401deb83407ab3da39eba7e33987a73c3df0c82b4bb5813ee871c19c41d48"
+dependencies = [
+ "futures-core",
+ "futures-macro",
+ "futures-task",
+ "pin-project-lite",
+ "pin-utils",
+ "slab",
+]
+
+[[package]]
+name = "gdk-pixbuf"
+version = "0.20.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8730751991b97419fc3f0c2dca2c9e45b48edf46e48e0f965964ecf33889812f"
+dependencies = [
+ "gdk-pixbuf-sys",
+ "gio",
+ "glib",
+ "libc",
+]
+
+[[package]]
+name = "gdk-pixbuf-sys"
+version = "0.20.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1ffbf649fd5b1c8c0f0feeb015b7533c3ef92da2887fb95ddd338bc2b1644a7c"
+dependencies = [
+ "gio-sys",
+ "glib-sys",
+ "gobject-sys",
+ "libc",
+ "system-deps",
+]
+
+[[package]]
+name = "gdk4"
+version = "0.9.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4b7d7237c1487ed4b300aac7744efcbf1319e12d60d7afcd6f505414bd5b5dea"
+dependencies = [
+ "cairo-rs",
+ "gdk-pixbuf",
+ "gdk4-sys",
+ "gio",
+ "glib",
+ "libc",
+ "pango",
+]
+
+[[package]]
+name = "gdk4-sys"
+version = "0.9.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a67576c8ec012156d7f680e201a807b4432a77babb3157e0555e990ab6bcd878"
+dependencies = [
+ "cairo-sys-rs",
+ "gdk-pixbuf-sys",
+ "gio-sys",
+ "glib-sys",
+ "gobject-sys",
+ "libc",
+ "pango-sys",
+ "pkg-config",
+ "system-deps",
+]
+
+[[package]]
+name = "gettext-rs"
+version = "0.7.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4a6716b8a0db461a2720b850ba1623e5b69e4b1aa0224cf5e1fb23a0fe49e65c"
+dependencies = [
+ "gettext-sys",
+ "locale_config",
+]
+
+[[package]]
+name = "gettext-sys"
+version = "0.21.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f7b8797f28f2dabfbe2caadb6db4f7fd739e251b5ede0a2ba49e506071edcf67"
+dependencies = [
+ "cc",
+ "temp-dir",
+]
+
+[[package]]
+name = "gio"
+version = "0.20.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "dcacaa37401cad0a95aadd266bc39c72a131d454fc012f6dfd217f891d76cc52"
+dependencies = [
+ "futures-channel",
+ "futures-core",
+ "futures-io",
+ "futures-util",
+ "gio-sys",
+ "glib",
+ "libc",
+ "pin-project-lite",
+ "smallvec",
+]
+
+[[package]]
+name = "gio-sys"
+version = "0.20.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5237611e97e9b86ab5768adc3eef853ae713ea797aa3835404acdfacffc9fb38"
+dependencies = [
+ "glib-sys",
+ "gobject-sys",
+ "libc",
+ "system-deps",
+ "windows-sys",
+]
+
+[[package]]
+name = "glib"
+version = "0.20.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "95648aac01b75503000bb3bcaa5ec7a7a2dd61e43636b8b1814854de94dd80e4"
+dependencies = [
+ "bitflags",
+ "futures-channel",
+ "futures-core",
+ "futures-executor",
+ "futures-task",
+ "futures-util",
+ "gio-sys",
+ "glib-macros",
+ "glib-sys",
+ "gobject-sys",
+ "libc",
+ "memchr",
+ "smallvec",
+]
+
+[[package]]
+name = "glib-macros"
+version = "0.20.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "302f1d633c9cdef4350330e7b68fd8016e2834bb106c93fdf9789fcde753c1ab"
+dependencies = [
+ "heck",
+ "proc-macro-crate",
+ "proc-macro2",
+ "quote",
+ "syn",
+]
+
+[[package]]
+name = "glib-sys"
+version = "0.20.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "92eee4531c1c9abba945d19378b205031b5890e1f99c319ba0503b6e0c06a163"
+dependencies = [
+ "libc",
+ "system-deps",
+]
+
+[[package]]
+name = "gobject-sys"
+version = "0.20.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "fa3d1dcd8a1eb2e7c22be3d5e792b14b186f3524f79b25631730f9a8c169d49a"
+dependencies = [
+ "glib-sys",
+ "libc",
+ "system-deps",
+]
+
+[[package]]
+name = "granite-rs"
+version = "1.3.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7299514cbcfda05321dc6e7546ebc6d4ea1cbc27dcc7f1dc9089fea27dbf4399"
+dependencies = [
+ "bitflags",
+ "gdk4",
+ "gio",
+ "glib",
+ "granite-rs-sys",
+ "gtk4",
+ "libc",
+ "once_cell",
+]
+
+[[package]]
+name = "granite-rs-sys"
+version = "0.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b0481fc89d9cf5ce0afb46978bd63dac19f3eb7324cb66156165b14e8c2e5ee0"
+dependencies = [
+ "gdk4-sys",
+ "gio-sys",
+ "glib-sys",
+ "gobject-sys",
+ "gtk4-sys",
+ "libc",
+ "system-deps",
+]
+
+[[package]]
+name = "graphene-rs"
+version = "0.20.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "80aac87f74e81c0e13433e892a047237abdc37945c86887f5eed905038356e69"
+dependencies = [
+ "glib",
+ "graphene-sys",
+ "libc",
+]
+
+[[package]]
+name = "graphene-sys"
+version = "0.20.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "cc2f91ecd32989efad60326cc20a8fb252bd2852239a08e4e70cde8c100de9ca"
+dependencies = [
+ "glib-sys",
+ "libc",
+ "pkg-config",
+ "system-deps",
+]
+
+[[package]]
+name = "gsk4"
+version = "0.9.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1f3cf2091e1af185b347b3450817d93dea6fe435df7abd4c2cd7fb5bcb4cfda8"
+dependencies = [
+ "cairo-rs",
+ "gdk4",
+ "glib",
+ "graphene-rs",
+ "gsk4-sys",
+ "libc",
+ "pango",
+]
+
+[[package]]
+name = "gsk4-sys"
+version = "0.9.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6aa69614a26d8760c186c3690f1b0fbb917572ca23ef83137445770ceddf8cde"
+dependencies = [
+ "cairo-sys-rs",
+ "gdk4-sys",
+ "glib-sys",
+ "gobject-sys",
+ "graphene-sys",
+ "libc",
+ "pango-sys",
+ "system-deps",
+]
+
+[[package]]
+name = "gtk4"
+version = "0.9.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f4fe572bf318e5dbc6f5a2f8a25d853f1ae3f42768c0b08af6ca20a18f4057e1"
+dependencies = [
+ "cairo-rs",
+ "field-offset",
+ "futures-channel",
+ "gdk-pixbuf",
+ "gdk4",
+ "gio",
+ "glib",
+ "graphene-rs",
+ "gsk4",
+ "gtk4-macros",
+ "gtk4-sys",
+ "libc",
+ "pango",
+]
+
+[[package]]
+name = "gtk4-macros"
+version = "0.9.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e9e7b362c8fccd2712297903717d65d30defdab2b509bc9d209cbe5ffb9fabaf"
+dependencies = [
+ "proc-macro-crate",
+ "proc-macro2",
+ "quote",
+ "syn",
+]
+
+[[package]]
+name = "gtk4-sys"
+version = "0.9.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1114a207af8ada02cf4658a76692f4190f06f093380d5be07e3ca8b43aa7c666"
+dependencies = [
+ "cairo-sys-rs",
+ "gdk-pixbuf-sys",
+ "gdk4-sys",
+ "gio-sys",
+ "glib-sys",
+ "gobject-sys",
+ "graphene-sys",
+ "gsk4-sys",
+ "libc",
+ "pango-sys",
+ "system-deps",
+]
+
+[[package]]
+name = "hashbrown"
+version = "0.14.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1"
+
+[[package]]
+name = "heck"
+version = "0.5.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea"
+
+[[package]]
+name = "indexmap"
+version = "2.5.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "68b900aa2f7301e21c36462b170ee99994de34dff39a4a6a528e80e7376d07e5"
+dependencies = [
+ "equivalent",
+ "hashbrown",
+]
+
+[[package]]
+name = "lazy_static"
+version = "1.5.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe"
+
+[[package]]
+name = "libc"
+version = "0.2.158"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d8adc4bb1803a324070e64a98ae98f38934d91957a99cfb3a43dcbc01bc56439"
+
+[[package]]
+name = "locale_config"
+version = "0.3.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "08d2c35b16f4483f6c26f0e4e9550717a2f6575bcd6f12a53ff0c490a94a6934"
+dependencies = [
+ "lazy_static",
+ "objc",
+ "objc-foundation",
+ "regex",
+ "winapi",
+]
+
+[[package]]
+name = "malloc_buf"
+version = "0.0.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "62bb907fe88d54d8d9ce32a3cceab4218ed2f6b7d35617cafe9adf84e43919cb"
+dependencies = [
+ "libc",
+]
+
+[[package]]
+name = "memchr"
+version = "2.7.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3"
+
+[[package]]
+name = "memoffset"
+version = "0.9.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "488016bfae457b036d996092f6cb448677611ce4449e970ceaf42695203f218a"
+dependencies = [
+ "autocfg",
+]
+
+[[package]]
+name = "objc"
+version = "0.2.7"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "915b1b472bc21c53464d6c8461c9d3af805ba1ef837e1cac254428f4a77177b1"
+dependencies = [
+ "malloc_buf",
+]
+
+[[package]]
+name = "objc-foundation"
+version = "0.1.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1add1b659e36c9607c7aab864a76c7a4c2760cd0cd2e120f3fb8b952c7e22bf9"
+dependencies = [
+ "block",
+ "objc",
+ "objc_id",
+]
+
+[[package]]
+name = "objc_id"
+version = "0.1.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c92d4ddb4bd7b50d730c215ff871754d0da6b2178849f8a2a2ab69712d0c073b"
+dependencies = [
+ "objc",
+]
+
+[[package]]
+name = "once_cell"
+version = "1.19.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92"
+
+[[package]]
+name = "pango"
+version = "0.20.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5764e5a174a5a0ec054fe5962ce6d4fc7052e2d0dcc23bbc77202b40a4a403d3"
+dependencies = [
+ "gio",
+ "glib",
+ "libc",
+ "pango-sys",
+]
+
+[[package]]
+name = "pango-sys"
+version = "0.20.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "fd317e1de76b14b3d3efe05518c08b360327f1ab7fec150473a89ffcad4b072d"
+dependencies = [
+ "glib-sys",
+ "gobject-sys",
+ "libc",
+ "system-deps",
+]
+
+[[package]]
+name = "pin-project-lite"
+version = "0.2.14"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "bda66fc9667c18cb2758a2ac84d1167245054bcf85d5d1aaa6923f45801bdd02"
+
+[[package]]
+name = "pin-utils"
+version = "0.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184"
+
+[[package]]
+name = "pkg-config"
+version = "0.3.30"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d231b230927b5e4ad203db57bbcbee2802f6bce620b1e4a9024a07d94e2907ec"
+
+[[package]]
+name = "proc-macro-crate"
+version = "3.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8ecf48c7ca261d60b74ab1a7b20da18bede46776b2e55535cb958eb595c5fa7b"
+dependencies = [
+ "toml_edit",
+]
+
+[[package]]
+name = "proc-macro2"
+version = "1.0.86"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5e719e8df665df0d1c8fbfd238015744736151d4445ec0836b8e628aae103b77"
+dependencies = [
+ "unicode-ident",
+]
+
+[[package]]
+name = "quote"
+version = "1.0.37"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b5b9d34b8991d19d98081b46eacdd8eb58c6f2b201139f7c5f643cc155a633af"
+dependencies = [
+ "proc-macro2",
+]
+
+[[package]]
+name = "regex"
+version = "1.10.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4219d74c6b67a3654a9fbebc4b419e22126d13d2f3c4a07ee0cb61ff79a79619"
+dependencies = [
+ "aho-corasick",
+ "memchr",
+ "regex-automata",
+ "regex-syntax",
+]
+
+[[package]]
+name = "regex-automata"
+version = "0.4.7"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "38caf58cc5ef2fed281f89292ef23f6365465ed9a41b7a7754eb4e26496c92df"
+dependencies = [
+ "aho-corasick",
+ "memchr",
+ "regex-syntax",
+]
+
+[[package]]
+name = "regex-syntax"
+version = "0.8.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7a66a03ae7c801facd77a29370b4faec201768915ac14a721ba36f20bc9c209b"
+
+[[package]]
+name = "rustc_version"
+version = "0.4.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "cfcb3a22ef46e85b45de6ee7e79d063319ebb6594faafcf1c225ea92ab6e9b92"
+dependencies = [
+ "semver",
+]
+
+[[package]]
+name = "semver"
+version = "1.0.23"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "61697e0a1c7e512e84a621326239844a24d8207b4669b41bc18b32ea5cbf988b"
+
+[[package]]
+name = "serde"
+version = "1.0.210"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c8e3592472072e6e22e0a54d5904d9febf8508f65fb8552499a1abc7d1078c3a"
+dependencies = [
+ "serde_derive",
+]
+
+[[package]]
+name = "serde_derive"
+version = "1.0.210"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "243902eda00fad750862fc144cea25caca5e20d615af0a81bee94ca738f1df1f"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn",
+]
+
+[[package]]
+name = "serde_spanned"
+version = "0.6.7"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "eb5b1b31579f3811bf615c144393417496f152e12ac8b7663bf664f4a815306d"
+dependencies = [
+ "serde",
+]
+
+[[package]]
+name = "shlex"
+version = "1.3.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64"
+
+[[package]]
+name = "slab"
+version = "0.4.9"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8f92a496fb766b417c996b9c5e57daf2f7ad3b0bebe1ccfca4856390e3d3bb67"
+dependencies = [
+ "autocfg",
+]
+
+[[package]]
+name = "smallvec"
+version = "1.13.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67"
+
+[[package]]
+name = "syn"
+version = "2.0.77"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9f35bcdf61fd8e7be6caf75f429fdca8beb3ed76584befb503b1569faee373ed"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "unicode-ident",
+]
+
+[[package]]
+name = "system-deps"
+version = "7.0.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "070a0a5e7da2d24be457809c4b3baa57a835fd2829ad8b86f9a049052fe71031"
+dependencies = [
+ "cfg-expr",
+ "heck",
+ "pkg-config",
+ "toml",
+ "version-compare",
+]
+
+[[package]]
+name = "target-lexicon"
+version = "0.12.16"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "61c41af27dd6d1e27b1b16b489db798443478cef1f06a660c96db617ba5de3b1"
+
+[[package]]
+name = "temp-dir"
+version = "0.1.13"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1f227968ec00f0e5322f9b8173c7a0cbcff6181a0a5b28e9892491c286277231"
+
+[[package]]
+name = "toml"
+version = "0.8.19"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a1ed1f98e3fdc28d6d910e6737ae6ab1a93bf1985935a1193e68f93eeb68d24e"
+dependencies = [
+ "serde",
+ "serde_spanned",
+ "toml_datetime",
+ "toml_edit",
+]
+
+[[package]]
+name = "toml_datetime"
+version = "0.6.8"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0dd7358ecb8fc2f8d014bf86f6f638ce72ba252a2c3a2572f2a795f1d23efb41"
+dependencies = [
+ "serde",
+]
+
+[[package]]
+name = "toml_edit"
+version = "0.22.20"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "583c44c02ad26b0c3f3066fe629275e50627026c51ac2e595cca4c230ce1ce1d"
+dependencies = [
+ "indexmap",
+ "serde",
+ "serde_spanned",
+ "toml_datetime",
+ "winnow",
+]
+
+[[package]]
+name = "unicode-ident"
+version = "1.0.13"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e91b56cd4cadaeb79bbf1a5645f6b4f8dc5bde8834ad5894a8db35fda9efa1fe"
+
+[[package]]
+name = "version-compare"
+version = "0.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "852e951cb7832cb45cb1169900d19760cfa39b82bc0ea9c0e5a14ae88411c98b"
+
+[[package]]
+name = "winapi"
+version = "0.3.9"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419"
+dependencies = [
+ "winapi-i686-pc-windows-gnu",
+ "winapi-x86_64-pc-windows-gnu",
+]
+
+[[package]]
+name = "winapi-i686-pc-windows-gnu"
+version = "0.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
+
+[[package]]
+name = "winapi-x86_64-pc-windows-gnu"
+version = "0.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
+
+[[package]]
+name = "windows-sys"
+version = "0.52.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d"
+dependencies = [
+ "windows-targets",
+]
+
+[[package]]
+name = "windows-targets"
+version = "0.52.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973"
+dependencies = [
+ "windows_aarch64_gnullvm",
+ "windows_aarch64_msvc",
+ "windows_i686_gnu",
+ "windows_i686_gnullvm",
+ "windows_i686_msvc",
+ "windows_x86_64_gnu",
+ "windows_x86_64_gnullvm",
+ "windows_x86_64_msvc",
+]
+
+[[package]]
+name = "windows_aarch64_gnullvm"
+version = "0.52.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3"
+
+[[package]]
+name = "windows_aarch64_msvc"
+version = "0.52.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469"
+
+[[package]]
+name = "windows_i686_gnu"
+version = "0.52.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b"
+
+[[package]]
+name = "windows_i686_gnullvm"
+version = "0.52.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66"
+
+[[package]]
+name = "windows_i686_msvc"
+version = "0.52.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66"
+
+[[package]]
+name = "windows_x86_64_gnu"
+version = "0.52.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78"
+
+[[package]]
+name = "windows_x86_64_gnullvm"
+version = "0.52.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d"
+
+[[package]]
+name = "windows_x86_64_msvc"
+version = "0.52.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec"
+
+[[package]]
+name = "winnow"
+version = "0.6.18"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "68a9bda4691f099d435ad181000724da8e5899daa10713c2d432552b9ccd3a6f"
+dependencies = [
+ "memchr",
+]
diff --git a/Cargo.toml b/Cargo.toml
new file mode 100644
index 000000000..bafb8343e
--- /dev/null
+++ b/Cargo.toml
@@ -0,0 +1,10 @@
+[package]
+name = "akira"
+version = "0.1.0"
+edition = "2021"
+
+[dependencies]
+gettext-rs = "0.7.1"
+granite = { version = "1.1", package = "granite-rs", features = ["v7_2"] }
+gtk = { version = "0.9.1", package = "gtk4" }
+once_cell = "1.19.0"
diff --git a/README.md b/README.md
index 521702bfb..90f9dbf60 100644
--- a/README.md
+++ b/README.md
@@ -1,45 +1,12 @@
-
-
-
-
-The Linux Design Tool
-
-
-
-
-
-
- Install •
- Compile •
- Questions •
- Contributing •
- Support •
- Mascot •
- License
-
-
-![screenshot](data/screenshots/screenshot-1.png)
-
-Akira is a native Linux Design application built in Vala and GTK. Akira focuses on offering a modern and fast approach to UI and UX Design, mainly targeting web designers and graphic designers. The main goal is to offer a valid and professional solution for designers who want to use Linux as their main OS.
+# Akira
-⚠️⚠️ **AKIRA IS CURRENTLY IN EARLY DEVELOPMENT, NOT READY TO BE USED FOR PRODUCTION!** ⚠️⚠️
-
-Feel free to download the Alpha and help us testing it.
+> The Linux Design Tool
-## 📦 Install
+⚠️⚠️ **AKIRA IS CURRENTLY IN EARLY DEVELOPMENT, NOT READY TO BE USED FOR PRODUCTION!** ⚠️⚠️
-| elementaryOS AppCenter | FlatHub |
-|------------------------ |--------------- |
-|[![Get it on AppCenter](https://appcenter.elementary.io/badge.svg)](https://appcenter.elementary.io/com.github.akiraux.akira/)|
+## Experimental Rust branch
-### Flathub Beta
-```
-flatpak remote-add flathub-beta https://flathub.org/beta-repo/flathub-beta.flatpakrepo
-flatpak install akira
-```
+Akira is a native Linux Design application built in Rust. Akira focuses on offering a modern and fast approach to UI and UX Design, mainly targeting web and graphic designers.
## 🛠 Compile
@@ -47,32 +14,11 @@ You can install Akira by compiling it from the source
### Install Dependencies
- - `gtk+-3.0>=3.18`
- - `granite>=6.0.0`
- - `glib-2.0`
- - `gee-0.8`
- - `gobject-2.0`
- - `libxml-2.0`
- - `libjson-glib-1.0`
- - `libarchive`
- - `gettext`
- - `cairo`
- - `meson`
-
-> _**Note:** For non-elementary distros, (such as Arch, Debian etc) you are required to install "vala", "elementary-theme" and "elementary-icon-theme" as additional dependencies._
+WIP
### Compile & Run
-Once the above mentioned dependencies are resolved, Akira can be compiled & installed
-
-```sh
-meson build --prefix=/usr -Dprofile=default
-cd build
-ninja && sudo ninja install
-./src/com.github.akiraux.akira
-```
-
-> _**Note:** Replace the `-Dprofile=default` with `-Dprofile=development` to compile and install Akira in **development** mode where you can make changes._
+WIP
## 🤔 Questions
@@ -99,13 +45,14 @@ If you like Akira and you want to support its development, consider donating via
![](https://raw.githubusercontent.com/akiraux/assets/master/mascot/akira-mascot-akari.png)
-**Akari the Cyber Phoenix** is a perfectionist. She is tidy, collected and has a sharp eye for detail. Her name Akari (灯理、) means *"the enlightenment of a sophisticated order"*. Her costume resembles the project's icon. Get the Mascot and all the other assets from [here](https://github.com/akiraux/assets).
+**Akari the Cyber Phoenix** is a perfectionist. She is tidy, collected and has a sharp eye for detail. Her name Akari (灯理、) means _"the enlightenment of a sophisticated order"_. Her costume resembles the project's icon. Get the Mascot and all the other assets from [here](https://github.com/akiraux/assets).
Mascot character designed by **Tyson Tan**.
Tyson Tan offers mascot design service for free and open source software, free of charge, under free license.
-Contact: [http://tysontan.com](http://tysontan.com) / [tysontan@mail.com](mailto:tysontan@mail.com)
+Contact: [http://tysontan.com](http://tysontan.com) / [tysontan@mail.com](mailto:tysontan@mail.com)
## 📜 License
+
#### [GNU GPLv3 / Creative Commons BY-SA](./COPYING)
-Copyright © 2019-2020 Akira Project.
+Copyright © 2019-2024 Alessandro Castellani.
diff --git a/akira-logo-transparent.png b/akira-logo-transparent.png
deleted file mode 100644
index fc83522da..000000000
Binary files a/akira-logo-transparent.png and /dev/null differ
diff --git a/akira-screenshot.png b/akira-screenshot.png
deleted file mode 100644
index 0b541a35e..000000000
Binary files a/akira-screenshot.png and /dev/null differ
diff --git a/aux/flatpak/com.github.akiraux.akira.json b/aux/flatpak/com.github.akiraux.akira.json
deleted file mode 100644
index c33eceb77..000000000
--- a/aux/flatpak/com.github.akiraux.akira.json
+++ /dev/null
@@ -1,106 +0,0 @@
-{
- "app-id": "com.github.akiraux.akiraDevel",
- "runtime": "org.gnome.Platform",
- "runtime-version": "40",
- "sdk": "org.gnome.Sdk",
- "base": "io.elementary.BaseApp",
- "base-version": "juno-20.08",
- "command": "com.github.akiraux.akiraDevel",
- "cleanup": [
- "/include",
- "/lib/pkgconfig",
- "/lib/debug",
- "/share/vala",
- "/man",
- "*.a",
- "*.la"
- ],
- "finish-args": [
- "--share=ipc",
- "--socket=fallback-x11",
- "--socket=wayland",
- "--talk-name=org.gtk.vfs.*",
- "--filesystem=xdg-run/gvfs",
- "--filesystem=xdg-run/gvfsd"
- ],
- "modules": [
- {
- "name": "elementary-stylesheet",
- "buildsystem": "meson",
- "sources": [{
- "type": "git",
- "url": "https://github.com/elementary/stylesheet.git",
- "commit": "3047efbfabe723e0b0f2b8ee3d53bed528be4b14"
- }],
- "modules": [{
- "name": "sassc",
- "cleanup": [
- "*"
- ],
- "sources": [{
- "type": "git",
- "url": "https://github.com/sass/sassc.git",
- "tag": "3.6.1"
- },
- {
- "type": "script",
- "dest-filename": "autogen.sh",
- "commands": [
- "autoreconf -si"
- ]
- }
- ],
- "modules": [{
- "name": "libsass",
- "cleanup": [
- "*"
- ],
- "sources": [{
- "type": "git",
- "url": "https://github.com/sass/libsass.git",
- "tag": "3.6.4"
- },
- {
- "type": "script",
- "dest-filename": "autogen.sh",
- "commands": [
- "autoreconf -si"
- ]
- }
- ]
- }]
- }]
- },
- {
- "name": "elementary-icons",
- "buildsystem": "meson",
- "sources": [{
- "type": "git",
- "url": "https://github.com/elementary/icons.git",
- "commit": "9e7ace3d6c1d1e3b5ea64012a371e46039bf044a"
- }],
- "modules": [{
- "name": "xcursorgen",
- "cleanup": [
- "*"
- ],
- "sources": [{
- "type": "git",
- "url": "https://gitlab.freedesktop.org/xorg/app/xcursorgen.git",
- "tag": "xcursorgen-1.0.7"
- }]
- }]
- },
- {
- "name": "akira",
- "buildsystem": "meson",
- "config-opts": [
- "-Dprofile=development"
- ],
- "sources": [{
- "type": "dir",
- "path": "../../"
- }]
- }
- ]
-}
diff --git a/aux/meson/post_install.py b/aux/meson/post_install.py
deleted file mode 100755
index 401004d21..000000000
--- a/aux/meson/post_install.py
+++ /dev/null
@@ -1,19 +0,0 @@
-#!/usr/bin/env python3
-
-import os
-import subprocess
-
-install_prefix = os.environ['MESON_INSTALL_PREFIX']
-schemadir = os.path.join(install_prefix, 'share/glib-2.0/schemas')
-
-if not os.environ.get('DESTDIR'):
- print('Compiling gsettings schemas...')
- subprocess.call(['glib-compile-schemas', schemadir])
-
- print('Updating icon cache...')
- icon_cache_dir = os.path.join(install_prefix, 'share/icons/hicolor')
- subprocess.call(['gtk-update-icon-cache', '-qtf', icon_cache_dir])
-
- print('Updating desktop database...')
- desktop_database_dir = os.path.join(install_prefix, 'share/applications')
- subprocess.call(['update-desktop-database', '-q', desktop_database_dir])
diff --git a/com.github.akiraux.akira.yml b/com.github.akiraux.akira.yml
deleted file mode 100644
index 7f6ad0263..000000000
--- a/com.github.akiraux.akira.yml
+++ /dev/null
@@ -1,23 +0,0 @@
-app-id: com.github.akiraux.akira
-runtime: io.elementary.Platform
-runtime-version: '6'
-sdk: io.elementary.Sdk
-command: com.github.akiraux.akira
-
-finish-args:
- - '--share=ipc'
- - '--socket=fallback-x11'
- - '--socket=wayland'
-
- # needed for perfers-color-scheme
- - '--system-talk-name=org.freedesktop.Accounts'
-
- - '--filesystem=home'
- - '--device=dri'
-
-modules:
- - name: akira
- buildsystem: meson
- sources:
- - type: dir
- path: .
diff --git a/data/assets.gresource.xml b/data/assets.gresource.xml
deleted file mode 100644
index 85dd3a710..000000000
--- a/data/assets.gresource.xml
+++ /dev/null
@@ -1,35 +0,0 @@
-
-
-
- css/colors.css
- css/layout.css
- css/artboard.css
- css/layer.css
- css/headerbar.css
- css/option-panel.css
- css/dialogs.css
-
-
- assets/akira-banner.jpg
-
- css/stylesheet.css
-
- icons/hicolor/document-layout.svg
- icons/symbolic/document-layout-symbolic.svg
-
- icons/symbolic/layer-visible-symbolic.svg
- icons/symbolic/layer-hidden-symbolic.svg
-
- icons/symbolic/input-hash-symbolic.svg
- icons/symbolic/input-percentage-symbolic.svg
- icons/symbolic/input-pixel-symbolic.svg
- icons/symbolic/input-degrees-symbolic.svg
-
- icons/symbolic/shape-image-symbolic.svg
- icons/symbolic/shape-pencil-symbolic.svg
- icons/symbolic/shape-rectangle-symbolic.svg
- icons/symbolic/shape-triangle-symbolic.svg
- icons/symbolic/shape-circle-symbolic.svg
- icons/symbolic/shape-text-symbolic.svg
-
-
diff --git a/data/assets/akira-banner.jpg b/data/assets/akira-banner.jpg
deleted file mode 100644
index 4a7a98d1a..000000000
Binary files a/data/assets/akira-banner.jpg and /dev/null differ
diff --git a/data/com.github.akiraux.akira.appdata.xml.in.in b/data/com.github.akiraux.akira.appdata.xml.in.in
deleted file mode 100644
index 3a58975dc..000000000
--- a/data/com.github.akiraux.akira.appdata.xml.in.in
+++ /dev/null
@@ -1,199 +0,0 @@
-
-
-
- @APP_ID@
- CC0-1.0
- GPL-3.0+
- Akira
- The Linux Design Tool
-
-
- A modern UX Design Application for UI and UX Designers
-
-
- ⚠ WARNING! Akira is still under development and not ready for production. Missing features, random bugs, and black holes opening in your kitchen are to be expected.
-
- Akira is a native Linux Design application built in Vala and Gtk. Akira focuses on offering a modern and fast approach to UI and UX Design, mainly targeting web and graphic designers. The main goal is to offer a valid and professional solution for designers who want to use Linux as their main OS.
-
-
- Features Include:
-
-
- - Fully vector canvas for infinite resizing without quality loss
- - Smart option panel that shows the editable features of a selected item
- - Layers panel with easy Drag and Drop and smart ordering
- - Create Artboards to better organize your design iterations and views
- - Control the size and quality of exported images
- - Customizable icon set
- - And so much more…
-
-
-
- @APP_ID@
-
-
-
-
- Performance improvements and Global colors library
-
- - Improved "Modes" detection (insert, select, transform).
- - Fixed Artboard label issues on zoom.
- - Improved Pixel Grid detection and z-index stack with other items.
- - Implemented editable zoom value.
- - Fix application activation when opening a new file.
- - Fix sizing issue when dropping images into the Canvas.
- - Implemented Global colors library.
- - Italian translation.
-
-
-
-
-
- New Features and Bug Fixes
-
- - Complete rebuild of the Canvas library architecture.
- - Implemented Pixel Grid.
- - Customize color of Pixel Grid.
- - Implemented smart Snapping Guides.
- - Customize color and magnetic threshold of Snapping Guides.
- - Allow items resizing in all directions.
- - Add images via click and drag with the Image Tool.
- - Handle multiple Fills and Border colors for each item.
- - Allow scaling items from the center.
- - Enable dropping images on the canvas.
- - A lot of code improvements and optimization.
-
-
-
-
-
- New Features and Bug Fixes
-
- - New color picker for Fills and Borders.
- - Zooming with mouse wheel follows the position of the cursor.
- - Fix loading Artboards background color when opening a file.
- - Fix numbering of newly created items.
- - Fix Gtk-CRITICAL warning when opening the Export Dialog.
- - Fix flipping items inside Artboards.
- - Fix crash when dropping flipped items inside Artboards.
- - General code improvements and optimization.
-
-
-
-
-
- Bug fixes and Artboards improvements
-
- - Control Artboards background color.
- - Hide and Lock Artboards from the Layers panel.
- - Items inside Artboards are masked when extending outside the edges of the Artboard.
- - Fix items reordering with the layers panel drag and drop.
- - Fix random segfault at startup while setting accelerators.
- - Updated goocanvas vapi.
-
-
-
-
-
- 🚀 Experimental Alpha Release, say Hi to Akira!
-
- - Create Artboards and basic shapes
- - Manage the fill and border properties of shapes
- - Import images
- - Export custom areas, selections, and artboards
- - So many crashes and missing features you wouldn't believe, but hey, this is an experimental alpha…
-
-
-
-
-
- 🚀 Experimental Alpha Release, say Hi to Akira!
-
- - Create Artboards and basic shapes
- - Manage the fill and border properties of shapes
- - Import images
- - Export custom areas, selections, and artboards
- - So many crashes and missing features you wouldn't believe, but hey, this is an experimental alpha…
-
-
-
-
-
- 🚀 Experimental Alpha Release, say Hi to Akira!
-
- - Create Artboards and basic shapes
- - Manage the fill and border properties of shapes
- - Import images
- - Export custom areas, selections, and artboards
- - So many crashes and missing features you wouldn't believe, but hey, this is an experimental alpha…
-
-
-
-
-
-
- https://raw.githubusercontent.com/akiraux/akira/master/data/screenshots/screenshot-1.png
-
-
- https://raw.githubusercontent.com/akiraux/akira/master/data/screenshots/screenshot-2.png
-
-
- https://raw.githubusercontent.com/akiraux/akira/master/data/screenshots/screenshot-3.png
-
-
- https://raw.githubusercontent.com/akiraux/akira/master/data/screenshots/screenshot-4.png
-
-
- @APP_ID@.desktop
- Alessandro Castellani
- https://github.com/akiraux/akira
- https://github.com/akiraux/akira/issues
- https://github.com/akiraux/akira/issues
- https://www.paypal.me/alecaddd
- castellani.ale@gmail.com
- @GETTEXT_PACKAGE@
-
-
- ModernToolkit
- HighContrast
- HiDpiIcon
-
-
- none
- none
- none
- none
- none
- none
- none
- none
- none
- none
- none
- none
- none
- none
- none
- none
- none
- none
- none
- none
- none
- none
- none
- none
- none
- none
- none
-
-
- #3f3f3f
- #ffffff
- 15
- pk_live_515yF9YDvXGakAYGJ74PQwmIwxs6xQrm0q0ULEAYO6vZyzsTIaOI40ZtDYj6qUGq6sjzCgwd25VQ4REbJob6pkB9r00tU1lgu6W
-
-
diff --git a/data/com.github.akiraux.akira.desktop.in.in b/data/com.github.akiraux.akira.desktop.in.in
deleted file mode 100644
index 5eb577887..000000000
--- a/data/com.github.akiraux.akira.desktop.in.in
+++ /dev/null
@@ -1,11 +0,0 @@
-[Desktop Entry]
-Name=Akira
-GenericName=Akira App
-Comment=The Linux Design Tool
-Categories=Utility;Graphics;
-Exec=@EXECUTABLE@
-Icon=@ICON_NAME@
-Terminal=false
-Type=Application
-Keywords=Design;Web;UX;UI;Graphics;
-MimeType=application/x-akira;
diff --git a/data/com.github.akiraux.akira.mime.xml b/data/com.github.akiraux.akira.mime.xml
deleted file mode 100644
index f1bfd2958..000000000
--- a/data/com.github.akiraux.akira.mime.xml
+++ /dev/null
@@ -1,9 +0,0 @@
-
-
-
- Akira Design File
-
-
-
-
-
diff --git a/data/css/artboard.css b/data/css/artboard.css
deleted file mode 100644
index cfd0e4135..000000000
--- a/data/css/artboard.css
+++ /dev/null
@@ -1,13 +0,0 @@
-row.artboard {
- transition: box-shadow 160ms ease, background-color 160ms ease;
- background-color: shade (@bg_color, 1);
-}
-
-row.artboard label {
- font-weight: bold;
- padding: 8px 0;
-}
-
-row.artboard:hover .actions {
- opacity: 1;
-}
diff --git a/data/css/colors.css b/data/css/colors.css
deleted file mode 100644
index 7faa04668..000000000
--- a/data/css/colors.css
+++ /dev/null
@@ -1,11 +0,0 @@
-.label-colors {
- color: alpha (@fg_color, 0.8);
-}
-
-.disabled {
- opacity: 0.5;
-}
-
-.border-bottom {
- border-bottom: 1px solid shade (@bg_color, 0.8);
-}
diff --git a/data/css/dialogs.css b/data/css/dialogs.css
deleted file mode 100644
index 29c844daa..000000000
--- a/data/css/dialogs.css
+++ /dev/null
@@ -1,30 +0,0 @@
-.warning-message {
- background-color: alpha (@STRAWBERRY_300, 0.2);
- border: 1px solid @STRAWBERRY_500;
- border-radius: 4px;
-}
-
-.banner {
- background-color: @bg_color;
- background-image:
- url("/com/github/akiraux/akira/akira-banner.jpg"),
- linear-gradient(
- to bottom,
- shade(@bg_color, 1.02),
- shade(@bg_color, 0.98)
- );
- background-position: center center;
- background-repeat: no-repeat;
- background-size: cover;
- border: 1px solid alpha(black, 0.15);
- border-radius: 6px;
- box-shadow:
- inset 0 0 0 1px alpha(white, 0.05),
- inset 0 1px 0 0 alpha(white, 0.45),
- inset 0 -1px 0 0 alpha(white, 0.15),
- 0 3px 2px -1px alpha(black, 0.15),
- 0 3px 5px alpha(black, 0.1);
- color: @fg_color;
- font-size: 32px;
- font-weight: 300;
-}
diff --git a/data/css/headerbar.css b/data/css/headerbar.css
deleted file mode 100644
index c398da796..000000000
--- a/data/css/headerbar.css
+++ /dev/null
@@ -1,41 +0,0 @@
-.headerbar-label {
- font-size: 8pt;
-}
-
-.button-zoom {
- padding: 0 6px;
-}
-
-.button-zoom-start {
- border-top-right-radius: 0px;
- border-bottom-right-radius: 0px;
-}
-
-.button-zoom-end {
- border-top-left-radius: 0px;
- border-bottom-left-radius: 0px;
-}
-
-entry.input-zoom {
- padding: 3px 8px 4px;
- margin: 6px;
-}
-
-.linked-flat button {
- background-color: shade (@bg_color, 1);
-}
-
-.export-titlebar {
- padding: 0;
-}
-
-/* Temporary elementary OS 6 stylesheet fixes */
-button.flat:disabled {
- background-color: transparent;
- box-shadow: none;
- border: none;
-}
-
-popover.menu stack {
- padding: 6px 10px;
-}
diff --git a/data/css/layer.css b/data/css/layer.css
deleted file mode 100644
index 7fa882246..000000000
--- a/data/css/layer.css
+++ /dev/null
@@ -1,42 +0,0 @@
-row {
- transition: box-shadow 160ms ease, background-color 160ms ease;
-}
-
-row:not(.item-property),
-row entry {
- background-color: @base_color;
-}
-
-row label {
- padding: 8px 0;
-}
-
-row:selected {
- background-color: alpha (@accent_color, 0.4);
-}
-
-row:hover:not(:selected) {
- box-shadow: inset 0 0 0 2px @accent_color;
-}
-
-.actions button {
- opacity: 0;
-}
-
-row:hover .actions button {
- opacity: 0.5;
-}
-
-row:hover .actions button:hover,
-row:hover .actions button.active,
-.actions button.active {
- opacity: 1;
-}
-
-.button-toggle.collapsed image {
- -gtk-icon-transform: rotate(-90deg);
-}
-
-.grid-motion {
- background-color: alpha (@accent_color, 0.3);
-}
diff --git a/data/css/layout.css b/data/css/layout.css
deleted file mode 100644
index 3c5653044..000000000
--- a/data/css/layout.css
+++ /dev/null
@@ -1,132 +0,0 @@
-.main-canvas {
- background-color: alpha (@fg_color, 0.05);
-}
-
-.sidebar-l {
- background-color: shade (@bg_color, 0.95);
- border-right: 1px solid shade (@bg_color, 0.9);
-}
-
-.sidebar-r {
- background-color: shade (@bg_color, 0.95);
- border-left: 1px solid shade (@bg_color, 0.9);
-}
-
-.layers-panel {
- background-color: alpha (@base_color, 0.7);
-}
-
-.sidebar-export-header {
- background-color: shade (@bg_color, 0.95);
- border-radius: 4px 0 0 0;
-}
-
-.sidebar-export {
- background-color: shade (@bg_color, 0.95);
- border-radius: 0 0 0 4px;
-}
-
-.color-chooser {
- padding: 8px 5px;
-}
-
-.color-grid flowboxchild {
- background-color: transparent;
-}
-
-.color-chooser label {
- font-size: 9pt;
- font-weight: bold;
- color: @fg_color;
-}
-
-.popover-toggler {
- padding: 3px;
- margin: 3px;
-}
-
-.popover-list row {
- padding: 3px;
-}
-
-.popover-list row:selected,
-.popover-list row:selected:hover {
- background-color: shade (@base_color, 0.85);
- color: shade (@fg_color, 0.7);
-}
-
-.popover-list row:hover {
- background-color: shade (@base_color, 0.9);
-}
-
-.alignment-panel {
- background-color: alpha (@base_color, 0.7);
- border-bottom: 1px solid shade (@bg_color, 0.8);
- padding: 3px;
-}
-
-.alignment-panel separator {
- border-right: none;
-}
-
-.button-rounded {
- border-radius: 50%;
- padding-left: 3px;
- padding-right: 3px;
-}
-
-.color-picker-button {
- border-radius: 0 3px 3px 0;
- border-left: none;
-}
-
-.group-title {
- font-size: 9pt;
- font-weight: 600;
- color: alpha (@fg_color, 0.9);
-}
-
-.entry-label {
- font-size: 8pt;
- font-weight: bold;
- color: alpha (@fg_color, 0.8);
-}
-
-.linked entry {
- padding: 3px 5px;
- border-left-width: 1px;
- border-radius: 2.5px;
-}
-
-.panel-separator {
- border: none;
-}
-
-paned > separator {
- min-width: 1px;
- margin-right: 0;
- margin-left: 0;
-}
-
-.export-panel {
- background-color: @bg_color;
-}
-
-.export-panel flowboxchild:focus {
- background-color: transparent;
-}
-
-.export-widget {
- background-color: shade (@bg_color, 0.98);
- padding: 9px;
- border-radius: 4px;
-}
-
-.export-image {
- border: 1px solid shade (@bg_color, 0.85);
-}
-
-.export-info {
- color: alpha (@fg_color, 0.7);
- font-size: 0.85em;
-}
diff --git a/data/css/option-panel.css b/data/css/option-panel.css
deleted file mode 100644
index 0aca09aad..000000000
--- a/data/css/option-panel.css
+++ /dev/null
@@ -1,51 +0,0 @@
-.option-panel {
- background-color: alpha (@base_color, 0.7);
- border-top: 1px solid shade (@bg_color, 0.7);
- border-bottom: 1px solid shade (@bg_color, 0.7);
-}
-
-.option-panel label {
- padding: 9px;
- font-size: 9pt;
- font-weight: bold;
- color: @fg_color;
-}
-
-.option-panel button {
- margin-right: 6px;
- border-radius: 50%;
-}
-
-.fills-list {
- background: transparent;
-}
-
-.bg-pattern {
- background-image: /* tint image */
- linear-gradient(to right, rgba(192, 192, 192, 0.75), rgba(192, 192, 192, 0.75)),
- /* checkered effect */
- linear-gradient(to right, black 50%, white 50%),
- linear-gradient(to bottom, black 50%, white 50%);
- background-blend-mode: normal, difference, normal;
- background-size: 8px 8px;
-}
-
-.selected-color-container {
- border-radius: 4px 0 0 4px;
-}
-
-button.selected-color {
- border-radius: 3px 0 0 3px;
- border: 1px solid;
-}
-
-.saved-color-button {
- border-radius: 4px;
-}
-
-/* spin button */
-.sidebar-l spinbutton.horizontal button.down,
-.sidebar-l spinbutton.horizontal button.up {
- -gtk-icon-transform: scale(0.7);
- padding: 0 1px;
-}
diff --git a/data/css/stylesheet.css b/data/css/stylesheet.css
deleted file mode 100644
index 455d1226e..000000000
--- a/data/css/stylesheet.css
+++ /dev/null
@@ -1,8 +0,0 @@
-/* akira stylesheet */
-@import url("css/colors.css");
-@import url("css/layout.css");
-@import url("css/artboard.css");
-@import url("css/headerbar.css");
-@import url("css/layer.css");
-@import url("css/option-panel.css");
-@import url("css/dialogs.css");
diff --git a/data/meson.build b/data/meson.build
deleted file mode 100644
index c57de70b7..000000000
--- a/data/meson.build
+++ /dev/null
@@ -1,84 +0,0 @@
-assets_dir = join_paths(akira_datadir, 'pixmaps', application_id)
-install_data(
- 'assets/akira-banner.jpg',
- install_dir: assets_dir
-)
-
-icon_sizes = ['16', '24', '32', '48', '64', '128']
-icons_dir = join_paths(akira_datadir, 'icons', 'hicolor')
-foreach size : icon_sizes
- install_data(
- join_paths('icons', size + 'x' + size, application_id + '.svg'),
- install_dir: join_paths(icons_dir, size + 'x' + size, 'apps')
- )
- install_data(
- join_paths('icons', size + 'x' + size, application_id + '.svg'),
- install_dir: join_paths(icons_dir, size + 'x' + size + '@2', 'apps')
- )
- install_data(
- join_paths('icons', size + 'x' + size, application_id + '.svg'),
- install_dir: join_paths(icons_dir, size + 'x' + size, 'mimetypes')
- )
-endforeach
-
-install_data(
- 'icons/128x128/' + meson.project_name() + '.svg',
- rename: application_id + '.svg',
- install_dir: join_paths(icons_dir, 'scalable', 'apps')
-)
-
-desktop_file_conf = configuration_data()
-desktop_file_conf.set('ICON_NAME', application_id)
-desktop_file_conf.set('EXECUTABLE', application_id)
-
-desktop_file = i18n.merge_file(
- input: configure_file(
- input: meson.project_name() + '.desktop.in.in',
- output: '@BASENAME@',
- configuration: desktop_file_conf
- ),
- output: application_id + '.desktop',
- po_dir: join_paths(meson.source_root(), 'po'),
- type: 'desktop',
- install: true,
- install_dir: join_paths(akira_datadir, 'applications')
-)
-if desktop_file_validate.found()
- test(
- 'validate-desktop',
- desktop_file_validate,
- args: [
- desktop_file.full_path()
- ]
- )
-endif
-
-appdata_file_conf = configuration_data()
-appdata_file_conf.set('APP_ID', application_id)
-appdata_file_conf.set('GETTEXT_PACKAGE', application_id)
-
-appdata_file = i18n.merge_file(
- input: configure_file(
- input: meson.project_name() + '.appdata.xml.in.in',
- output: '@BASENAME@',
- configuration: appdata_file_conf
- ),
- output: application_id + '.appdata.xml',
- po_dir: join_paths(meson.source_root(), 'po'),
- install: true,
- install_dir: join_paths(akira_datadir, 'metainfo')
-)
-if appstream_util.found()
- test(
- 'validate-appdata', appstream_util,
- args: [
- 'validate-relax', '--nonet', appdata_file.full_path()
- ]
- )
-endif
-
-install_data(
- meson.project_name() + '.mime.xml',
- install_dir: join_paths(akira_datadir, 'mime', 'packages')
-)
-subdir('schemas')
diff --git a/data/schemas/com.github.akiraux.akira.gschema.xml.in b/data/schemas/com.github.akiraux.akira.gschema.xml.in
deleted file mode 100644
index 0e8c401b9..000000000
--- a/data/schemas/com.github.akiraux.akira.gschema.xml.in
+++ /dev/null
@@ -1,195 +0,0 @@
-
-
-
- '0.0.0'
- The currently installed version.
- The currently installed version of Akira, updated only after the user launched the app. This is used to know when to trigger the Release Dialog.
-
-
-
- 360
- The saved horizontal position of the window.
- The saved horizontal position of the window.
-
-
-
- 360
- The vertical position width of the window.
- The saved vertical position of the window.
-
-
-
- 1024
- The saved width of the window.
- The saved width of the window.
-
-
-
- 768
- The saved height of the window.
- The saved height of the window.
-
-
-
- 804
- The saved width of the right panel.
- The saved width of the right panel containing the MainCanvas and RightSidebar.
-
-
-
- 220
- The saved width of the left panel.
- The saved width of the left panel. Must be greater than 220, or it will not take effect.
-
-
-
- false
- Use dark theme
- Switch between Light and Dark theme.
-
-
-
- true
- Follow system theme variation
- Follow system theme dark/light variation
-
-
-
- true
- Show button labels
- Show or Hide the button labels to slim the UI.
-
-
-
- false
- Use Symbolic Icons
- Allow user to choose between normal and symbolic icons in HeaderBar.
-
-
-
- false
- Invert Panels Order
- Allow user to choose between default and inverted panels order.
-
-
-
- '#888888'
- Default Grid Color.
- The default color of the pixel grid.
-
-
-
- true
- Enable Snapping Guides
- Allow user to enable or disable the snapping guides when moving items.
-
-
-
- '#ff0000'
- Default Snaps Color.
- The default color of the snapping guides.
-
-
-
- 4
- Default Snaps Sensitivity.
- The default sensitivity of the snapping threshold.
-
-
-
- '#CCCCCC'
- Default Shape Color.
- The default color of a newly created shape.
-
-
-
- true
- Add Border on Shape Creation
- Enable the addition of the border style when creating a new shape.
-
-
-
- 1
- Default Border Width.
- The default width of the border for a newly created shape.
-
-
-
- '#AAAAAA'
- Default Border Color.
- The default color of the border for a newly created shape.
-
-
-
- false
- Auto Reopen latest file
- Automatically reopen the latest file on startup.
-
-
-
- []
- Recently opened files
- Keep track of the 10 most recently opened files.
-
-
-
- ''
- Default export folder.
- The default folder where exported images will be saved.
-
-
-
- 1000
- The saved width of the export dialog.
- The saved width of the export dialog.
-
-
-
- 600
- The saved height of the export dialog.
- The saved height of the export dialog.
-
-
-
- 300
- The saved position of the export left panel.
- The saved position of the left panel in the export dialog.
-
-
-
- 100
- The quality value for exporting JPG images.
- The quality value for exporting JPG images in the export dialog.
-
-
-
- 0
- The compression value for exporting PNG images.
- The compression value for exporting PNG images in the export dialog.
-
-
-
- 'png'
- The format type for exporting images.
- The format type for exporting images in the export dialog.
-
-
-
- 1
- The scaled resolution for exporting images.
- The scaled resolution for exporting images in the export dialog.
-
-
-
- true
- The alpha setting for exporting PNG images.
- The alpha setting for exporting PNG images in the export dialog.
-
-
-
- []
- The list of global colors
- Keep track of the colors saved by the user and available in every document file.
-
-
-
diff --git a/data/schemas/meson.build b/data/schemas/meson.build
deleted file mode 100644
index bb14630dd..000000000
--- a/data/schemas/meson.build
+++ /dev/null
@@ -1,11 +0,0 @@
-schemas_conf = configuration_data()
-schemas_conf.set('SCHEMA_ID', application_id)
-schemas_conf.set('SCHEMA_PATH', schema_path)
-schemas_conf.set('GETTEXT_PACKAGE', gettext_package)
-
-configure_file(
- input: meson.project_name() + '.gschema.xml.in',
- output: application_id + '.gschema.xml',
- configuration: schemas_conf,
- install_dir: join_paths(akira_datadir, 'glib-2.0', 'schemas')
-)
diff --git a/data/screenshots/screenshot-1.png b/data/screenshots/screenshot-1.png
deleted file mode 100644
index 77a4fd1ca..000000000
Binary files a/data/screenshots/screenshot-1.png and /dev/null differ
diff --git a/data/screenshots/screenshot-2.png b/data/screenshots/screenshot-2.png
deleted file mode 100644
index f025b2dfe..000000000
Binary files a/data/screenshots/screenshot-2.png and /dev/null differ
diff --git a/data/screenshots/screenshot-3.png b/data/screenshots/screenshot-3.png
deleted file mode 100644
index 61c43b3de..000000000
Binary files a/data/screenshots/screenshot-3.png and /dev/null differ
diff --git a/data/screenshots/screenshot-4.png b/data/screenshots/screenshot-4.png
deleted file mode 100644
index acd747f84..000000000
Binary files a/data/screenshots/screenshot-4.png and /dev/null differ
diff --git a/meson.build b/meson.build
deleted file mode 100644
index acbd73fff..000000000
--- a/meson.build
+++ /dev/null
@@ -1,72 +0,0 @@
-# project name and programming language
-project('com.github.akiraux.akira', 'vala', 'c',
- default_options: 'default_library=static')
-
-akira_prefix = get_option('prefix')
-akira_datadir = join_paths(akira_prefix, get_option('datadir'))
-akira_pkgdatadir = join_paths(akira_datadir, meson.project_name())
-install_tests = get_option('install-tests')
-
-source_root = meson.current_source_dir()
-vapi_dir = join_paths(source_root, 'vapi')
-add_project_arguments('--vapidir=' + vapi_dir, language: 'vala')
-
-# Include the translations module
-i18n = import('i18n')
-# Dependencies
-gtk_dependency = dependency('gtk+-3.0')
-granite_dependency = dependency('granite', version: '>= 6.0.0')
-gee_dependency = dependency('gee-0.8')
-libxml_dependency = dependency('libxml-2.0')
-cairo_dependency = dependency('cairo', version: '>=1.14')
-libarchive_dependency = dependency('libarchive')
-json_glib_dependency = dependency('json-glib-1.0')
-
-# Optional dependencies
-desktop_file_validate = find_program('desktop-file-validate', required: false)
-appstream_util = find_program('appstream-util', required: false)
-
-# Include the gnome module
-gnome = import('gnome')
-asresources = gnome.compile_resources(
- 'as-resources', 'data/assets.gresource.xml',
- source_dir: 'data',
- c_name: 'as'
-)
-
-cc = meson.get_compiler('c')
-m_dep = cc.find_library('m', required: true)
-
-vala_lint = find_program('io.elementary.vala-lint', required : false)
-if vala_lint.found()
- test (
- 'Vala lint',
- vala_lint,
- args: ['-d', join_paths(meson.source_root(), 'src')]
- )
-endif
-
-# Set up the profile
-profile = get_option('profile')
-if profile == 'development'
- application_id = meson.project_name() + 'Devel'
- schema_path = '/com/github/akiraux/akiraDevel/'
-else
- application_id = meson.project_name()
- schema_path = '/com/github/akiraux/akira/'
-endif
-gettext_package = application_id
-
-# Set our translation domain
-add_global_arguments('-DGETTEXT_PACKAGE="@0@"'.format (gettext_package), language:'c')
-add_global_arguments(['-DG_LOG_DOMAIN="Akira"'], language:'c')
-
-subdir('src')
-subdir('data')
-subdir('po')
-
-if install_tests
- subdir('tests')
-endif
-
-meson.add_install_script('aux/meson/post_install.py')
diff --git a/meson_options.txt b/meson_options.txt
deleted file mode 100644
index b475d4c26..000000000
--- a/meson_options.txt
+++ /dev/null
@@ -1,4 +0,0 @@
-option('profile', type: 'combo', choices: ['default', 'development'], value: 'default')
-
-option('install-tests', type : 'boolean', value : 'false',
- description : 'install test executables')
diff --git a/po/LINGUAS b/po/LINGUAS
deleted file mode 100644
index ec99956ee..000000000
--- a/po/LINGUAS
+++ /dev/null
@@ -1,195 +0,0 @@
-da
-mh
-ps
-rm
-sn
-uk
-si
-mk
-hu
-nv
-id
-mo
-zh_HK
-my
-he
-eu
-ia
-km
-jv
-as
-cr
-ay
-kl
-vi
-ak
-uz
-kr
-zu
-gl
-is
-ha
-lo
-la
-ii
-kv
-so
-zh_CN
-sa
-ro
-ff
-cu
-fi
-lg
-sm
-te
-ig
-sw
-iu
-mt
-ki
-ky
-zh
-kk
-oc
-ko
-su
-ar
-fr
-ce
-mi
-bs
-am
-bn
-dz
-ny
-tl
-ty
-br
-ks
-hi
-th
-sr
-co
-bg
-io
-nl
-gd
-hy
-ch
-ta
-oj
-nn
-wa
-bh
-bm
-pa
-ur
-az
-yi
-hr
-bo
-cs
-fa
-wo
-cy
-eo
-pt
-li
-nr
-fr_CA
-lv
-pi
-lu
-ho
-ee
-kw
-tt
-ts
-sl
-mg
-om
-ae
-ug
-ve
-pl
-sg
-mr
-tw
-nd
-lt
-ast
-af
-ms
-se
-ti
-fo
-sma
-ht
-kn
-nb
-en_AU
-lb
-kj
-sq
-na
-et
-qu
-ku
-sd
-en_CA
-mn
-to
-fj
-st
-pt_BR
-ja
-xh
-ab
-ik
-av
-hz
-ckb
-ng
-gv
-ss
-aa kg
-rue
-en_GB
-tg
-ba
-ln
-ga
-cv
-sc
-el
-tr
-sk
-za
-fy
-ie
-dv
-it
-rw
-ml
-es
-ca
-os
-gn
-zh_TW
-vo
-bi
-or
-ru
-be
-no
-gu
-an
-tk
-ka
-ne
-rn
-tn
-de
-sv
-yo
diff --git a/po/aa.po b/po/aa.po
deleted file mode 100644
index 7d7bf5d53..000000000
--- a/po/aa.po
+++ /dev/null
@@ -1,4 +0,0 @@
-msgid ""
-msgstr ""
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
diff --git a/po/ab.po b/po/ab.po
deleted file mode 100644
index 7d7bf5d53..000000000
--- a/po/ab.po
+++ /dev/null
@@ -1,4 +0,0 @@
-msgid ""
-msgstr ""
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
diff --git a/po/ae.po b/po/ae.po
deleted file mode 100644
index 7d7bf5d53..000000000
--- a/po/ae.po
+++ /dev/null
@@ -1,4 +0,0 @@
-msgid ""
-msgstr ""
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
diff --git a/po/af.po b/po/af.po
deleted file mode 100644
index 7d7bf5d53..000000000
--- a/po/af.po
+++ /dev/null
@@ -1,4 +0,0 @@
-msgid ""
-msgstr ""
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
diff --git a/po/ak.po b/po/ak.po
deleted file mode 100644
index 7d7bf5d53..000000000
--- a/po/ak.po
+++ /dev/null
@@ -1,4 +0,0 @@
-msgid ""
-msgstr ""
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
diff --git a/po/am.po b/po/am.po
deleted file mode 100644
index 7d7bf5d53..000000000
--- a/po/am.po
+++ /dev/null
@@ -1,4 +0,0 @@
-msgid ""
-msgstr ""
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
diff --git a/po/an.po b/po/an.po
deleted file mode 100644
index 7d7bf5d53..000000000
--- a/po/an.po
+++ /dev/null
@@ -1,4 +0,0 @@
-msgid ""
-msgstr ""
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
diff --git a/po/ar.po b/po/ar.po
deleted file mode 100644
index d91cc1009..000000000
--- a/po/ar.po
+++ /dev/null
@@ -1,711 +0,0 @@
-msgid ""
-msgstr ""
-"Project-Id-Version: \n"
-"POT-Creation-Date: 2020-09-06 14:27+0300\n"
-"PO-Revision-Date: \n"
-"Last-Translator: \n"
-"Language-Team: \n"
-"Language: ar\n"
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
-"Content-Transfer-Encoding: 8bit\n"
-"X-Generator: Poedit 2.4.1\n"
-"X-Poedit-Basepath: ../src\n"
-"X-Poedit-SearchPath-0: .\n"
-
-#: Dialogs/ExportDialog.vala:151
-msgid "Export to:"
-msgstr "التصدير الى:"
-
-#: Dialogs/ExportDialog.vala:157
-msgid "Select Folder"
-msgstr "اختر مجلد"
-
-#: Dialogs/ExportDialog.vala:166
-msgid "Format:"
-msgstr "الصيغة:"
-
-#: Dialogs/ExportDialog.vala:179
-msgid "Quality:"
-msgstr "الجودة:"
-
-#: Dialogs/ExportDialog.vala:191
-msgid "Compression:"
-msgstr "الضغط:"
-
-#: Dialogs/ExportDialog.vala:205
-msgid "Transparency:"
-msgstr "الشفافية:"
-
-#: Dialogs/ExportDialog.vala:218
-msgid "Scale:"
-msgstr "الحجم:"
-
-#: Dialogs/ExportDialog.vala:242 FileFormat/FileManager.vala:49
-#: FileFormat/FileManager.vala:105
-msgid "Cancel"
-msgstr "إلغاء"
-
-#: Dialogs/ExportDialog.vala:249 Dialogs/ShortcutsDialog.vala:63
-#: Layouts/HeaderBar.vala:112
-msgid "Export"
-msgstr "تصدير"
-
-#: Dialogs/ReleaseDialog.vala:47 Dialogs/SettingsDialog.vala:217
-msgid ""
-"WARNING!\n"
-"Akira is still under development and not ready for production. Missing "
-"features, random bugs, and black holes opening in your kitchen are to be "
-"expected."
-msgstr ""
-"تحدير!\n"
-"لا يزال أكيرا تحت التطوير وغير جاهز للاستخدام النهائي.عليك توقع العديد "
-"من المزايا المفقودة والمشاكل البرمجية، وقد تؤدي الى ثقوب سوداء في مطبخك."
-
-#: Dialogs/ReleaseDialog.vala:100 Dialogs/SettingsDialog.vala:249
-msgid "Make a Donation"
-msgstr "قم بالتبرع"
-
-#: Dialogs/ReleaseDialog.vala:109 Dialogs/SettingsDialog.vala:258
-msgid "Suggest Translations"
-msgstr "اقترح ترجمة"
-
-#: Dialogs/ReleaseDialog.vala:118 Dialogs/SettingsDialog.vala:267
-msgid "Report a Problem"
-msgstr "بلغ عن مشكلة"
-
-#: Dialogs/SettingsDialog.vala:40
-msgid "Preferences"
-msgstr "التفضيلات"
-
-#: Dialogs/SettingsDialog.vala:50 Dialogs/SettingsDialog.vala:73
-#: Dialogs/ShortcutsDialog.vala:45
-msgid "General"
-msgstr "عام"
-
-#: Dialogs/SettingsDialog.vala:51 Dialogs/SettingsDialog.vala:86
-msgid "Interface"
-msgstr "الواجهة"
-
-#: Dialogs/SettingsDialog.vala:52 Layouts/HeaderBar.vala:280
-msgid "Shapes"
-msgstr "الأشكال"
-
-#: Dialogs/SettingsDialog.vala:53
-msgid "About"
-msgstr "عن"
-
-#: Dialogs/SettingsDialog.vala:74
-msgid "Auto Reopen Latest File:"
-msgstr "فتح آخر ملف تلقائياً:"
-
-#: Dialogs/SettingsDialog.vala:88
-msgid "Use Dark Theme:"
-msgstr "استخدام السمة الداكنة:"
-
-#: Dialogs/SettingsDialog.vala:92
-msgid "Invert Panels Order:"
-msgstr "عكس ترتيب اللوحات:"
-
-#: Dialogs/SettingsDialog.vala:96
-msgid "Restart application to apply this change."
-msgstr "عليك اعادة تشغيل البرنامج لتطبيق التغييرات."
-
-#: Dialogs/SettingsDialog.vala:100
-msgid "ToolBar Style"
-msgstr "نمط شريط الادوات"
-
-#: Dialogs/SettingsDialog.vala:102
-msgid "Show Button Labels:"
-msgstr "أظهر اسماء الأزرار:"
-
-#: Dialogs/SettingsDialog.vala:106
-msgid "Use Symbolic Icons:"
-msgstr "إستخدم ايقونات رمزية:"
-
-#: Dialogs/SettingsDialog.vala:129
-msgid "Default Colors"
-msgstr "الألوان الافتراضية"
-
-#: Dialogs/SettingsDialog.vala:131
-msgid "Define the default style used when creating a new shape."
-msgstr "تحديد النمط الافتراضي المستخدم عند إنشاء شكل جديد."
-
-#: Dialogs/SettingsDialog.vala:136
-msgid "Fill Color:"
-msgstr "لون الملء:"
-
-#: Dialogs/SettingsDialog.vala:157
-msgid "Enable Border Style:"
-msgstr "تفعيل نمط الحد الخارجي:"
-
-#: Dialogs/SettingsDialog.vala:160
-msgid "Border Color:"
-msgstr "لون الحدود:"
-
-#: Dialogs/SettingsDialog.vala:181
-msgid "Border Width:"
-msgstr "سماكة الحدود:"
-
-#: Dialogs/SettingsDialog.vala:209
-msgid "The Linux Design Tool"
-msgstr "أداة تصميم لينكس"
-
-#: Dialogs/SettingsDialog.vala:226
-msgid "Thanks to our awesome supporters!"
-msgstr "شكراً لداعمينا الرائعين!"
-
-#: Dialogs/SettingsDialog.vala:231
-msgid "View the list of supporters"
-msgstr "عرض قائمة الداعمين"
-
-#: Dialogs/ShortcutsDialog.vala:46
-msgid "New window:"
-msgstr "نافذة جديدة:"
-
-#: Dialogs/ShortcutsDialog.vala:48
-msgid "Preferences:"
-msgstr "التفضيلات:"
-
-#: Dialogs/ShortcutsDialog.vala:50
-msgid "Quit:"
-msgstr "خروج:"
-
-#: Dialogs/ShortcutsDialog.vala:52
-msgid "Presentation mode:"
-msgstr "وضع التقديم:"
-
-#: Dialogs/ShortcutsDialog.vala:55
-msgid "File"
-msgstr "ملف"
-
-#: Dialogs/ShortcutsDialog.vala:56
-msgid "Open:"
-msgstr "فتح:"
-
-#: Dialogs/ShortcutsDialog.vala:58
-msgid "Save:"
-msgstr "حفظ:"
-
-#: Dialogs/ShortcutsDialog.vala:60
-msgid "Save as:"
-msgstr "حفظ باسم:"
-
-#: Dialogs/ShortcutsDialog.vala:64
-msgid "Export artboards:"
-msgstr "تصدير اللوحات:"
-
-#: Dialogs/ShortcutsDialog.vala:66
-msgid "Export selection:"
-msgstr "تصدير العناصر المحددة:"
-
-#: Dialogs/ShortcutsDialog.vala:68
-msgid "Highlight area to export:"
-msgstr "حدد المنطقة المراد تصديرها:"
-
-#: Dialogs/ShortcutsDialog.vala:77
-msgid "Canvas"
-msgstr "مساحة العمل"
-
-#: Dialogs/ShortcutsDialog.vala:78
-msgid "Zoom in:"
-msgstr "تكبير:"
-
-#: Dialogs/ShortcutsDialog.vala:80
-msgid "Zoom out:"
-msgstr "تصغير:"
-
-#: Dialogs/ShortcutsDialog.vala:82
-msgid "Zoom reset:"
-msgstr "اعادة تعيين الحجم:"
-
-#: Dialogs/ShortcutsDialog.vala:85
-msgid "Item creation"
-msgstr "إنشاء غرض"
-
-#: Dialogs/ShortcutsDialog.vala:86
-msgid "Artboard:"
-msgstr "المساحة الفنية:"
-
-#: Dialogs/ShortcutsDialog.vala:88
-msgid "Rectangle:"
-msgstr "مستطيل:"
-
-#: Dialogs/ShortcutsDialog.vala:90
-msgid "Ellipse:"
-msgstr "شكل بيضاوي:"
-
-#: Dialogs/ShortcutsDialog.vala:92
-msgid "Text:"
-msgstr "نص:"
-
-#: Dialogs/ShortcutsDialog.vala:94
-msgid "Image:"
-msgstr "صورة:"
-
-#: Dialogs/ShortcutsDialog.vala:97 Layouts/Partials/TransformPanel.vala:174
-msgid "Transform"
-msgstr "التحول"
-
-#: Dialogs/ShortcutsDialog.vala:98
-msgid "Raise selection:"
-msgstr "ارفع المحدد:"
-
-#: Dialogs/ShortcutsDialog.vala:100
-msgid "Lower selection:"
-msgstr "اخفض المحدد:"
-
-#: Dialogs/ShortcutsDialog.vala:102
-msgid "Raise selection to top:"
-msgstr "ارفع المحدد للقمة:"
-
-#: Dialogs/ShortcutsDialog.vala:104
-msgid "Lower selection to bottom:"
-msgstr "اخفض المحدد للقاع:"
-
-#: Dialogs/ShortcutsDialog.vala:106
-msgid "Flip horizontally:"
-msgstr "قلب افقي:"
-
-#: Dialogs/ShortcutsDialog.vala:108
-msgid "Flip vertically:"
-msgstr "قلب عمودي:"
-
-#: FileFormat/FileManager.vala:46
-msgid "Save Akira file"
-msgstr "حفظ ملف أكيرا"
-
-#: FileFormat/FileManager.vala:48 Layouts/HeaderBar.vala:190
-msgid "Save"
-msgstr "حفظ"
-
-#: FileFormat/FileManager.vala:71
-msgid "Akira files"
-msgstr "ملفات أكيرا"
-
-#: FileFormat/FileManager.vala:76
-msgid "All files"
-msgstr "كل الملفات"
-
-#: FileFormat/FileManager.vala:103
-msgid "Open Akira file"
-msgstr "فتح ملف أكيرا"
-
-#: FileFormat/FileManager.vala:105 Layouts/HeaderBar.vala:170
-msgid "Open"
-msgstr "فتح"
-
-#: Layouts/HeaderBar.vala:69 Lib/Managers/ExportManager.vala:296
-msgid "Untitled"
-msgstr "بدون عنوان"
-
-#: Layouts/HeaderBar.vala:71
-msgid "Menu"
-msgstr "القائمة"
-
-#: Layouts/HeaderBar.vala:75
-msgid "Insert"
-msgstr "ادراج"
-
-#: Layouts/HeaderBar.vala:82
-msgid "Group"
-msgstr "تجميع"
-
-#: Layouts/HeaderBar.vala:84
-msgid "Ungroup"
-msgstr "تفكيك"
-
-#: Layouts/HeaderBar.vala:87
-msgid "Up"
-msgstr "للأعلى"
-
-#: Layouts/HeaderBar.vala:92
-msgid "Down"
-msgstr "للأسفل"
-
-#: Layouts/HeaderBar.vala:97
-msgid "Top"
-msgstr "للقمة"
-
-#: Layouts/HeaderBar.vala:102
-msgid "Bottom"
-msgstr "للقاع"
-
-#: Layouts/HeaderBar.vala:107
-msgid "Settings"
-msgstr "الاعدادات"
-
-#: Layouts/HeaderBar.vala:118
-msgid "Difference"
-msgstr "الفرق"
-
-#: Layouts/HeaderBar.vala:120
-msgid "Exclusion"
-msgstr "استثناء"
-
-#: Layouts/HeaderBar.vala:122
-msgid "Intersect"
-msgstr "تداخل"
-
-#: Layouts/HeaderBar.vala:124
-msgid "Union"
-msgstr "اتحاد"
-
-#: Layouts/HeaderBar.vala:161
-msgid "New Window"
-msgstr "نافذة جديدة"
-
-#: Layouts/HeaderBar.vala:182
-msgid "Open Recent"
-msgstr "فتح المستندات الاخيرة"
-
-#: Layouts/HeaderBar.vala:195
-msgid "Save As"
-msgstr "حفظ باسم"
-
-#: Layouts/HeaderBar.vala:204
-msgid "Quit"
-msgstr "خروج"
-
-#: Layouts/HeaderBar.vala:237
-msgid "Artboard"
-msgstr "مساحة فنية"
-
-#: Layouts/HeaderBar.vala:254
-msgid "Add Items"
-msgstr "اضافة عناصر"
-
-#: Layouts/HeaderBar.vala:262
-msgid "Rectangle"
-msgstr "مستطيل"
-
-#: Layouts/HeaderBar.vala:268
-msgid "Ellipse"
-msgstr "شكل بيضاوي"
-
-#: Layouts/HeaderBar.vala:286
-msgid "Vector"
-msgstr "متجه"
-
-#: Layouts/HeaderBar.vala:288
-msgid "Pencil"
-msgstr "قلم رصاص"
-
-#: Layouts/HeaderBar.vala:291
-msgid "Text"
-msgstr "نص"
-
-#: Layouts/HeaderBar.vala:297
-msgid "Image"
-msgstr "صورة"
-
-#: Layouts/HeaderBar.vala:330
-msgid "Export Current Selection"
-msgstr "تصدير العناصر المحددة"
-
-#: Layouts/HeaderBar.vala:336
-msgid "Export Artboards"
-msgstr "تصدير اللوحات"
-
-#: Layouts/HeaderBar.vala:345
-msgid "Highlight Area to Export"
-msgstr "حدد المنطقة المراد تصديرها"
-
-#: Layouts/HeaderBar.vala:391
-msgid "Main Menu"
-msgstr "القائمة الرئيسة"
-
-#: Layouts/HeaderBar.vala:468 Services/ActionManager.vala:224
-#: Services/ActionManager.vala:243 Services/ActionManager.vala:262
-#, c-format
-msgid "Unable to open file at '%s'"
-msgstr "غير قادر فتح الملف في '%s'"
-
-#: Layouts/MainCanvas.vala:46
-msgid "Button was pressed!"
-msgstr "تم ضغط زر!"
-
-#: Layouts/MainCanvas.vala:206
-msgid "Export completed!"
-msgstr "انتهى التصدير!"
-
-#: Layouts/Partials/AlignItemsPanel.vala:48
-msgid "Distribute Horizontally"
-msgstr "توزيع بشكل أفقي"
-
-#: Layouts/Partials/AlignItemsPanel.vala:50
-msgid "Distribute Vertically"
-msgstr "توزيع بشكل عمودي"
-
-#: Layouts/Partials/AlignItemsPanel.vala:52
-msgid "Align Left"
-msgstr "محاذاة يساراً"
-
-#: Layouts/Partials/AlignItemsPanel.vala:53
-msgid "Align Center"
-msgstr "توسيط"
-
-#: Layouts/Partials/AlignItemsPanel.vala:54
-msgid "Align Right"
-msgstr "محاذاة يميناً"
-
-#: Layouts/Partials/AlignItemsPanel.vala:56
-msgid "Align Top"
-msgstr "محاذاة للقمة"
-
-#: Layouts/Partials/AlignItemsPanel.vala:57
-msgid "Align Middle"
-msgstr "توسيط عمودي"
-
-#: Layouts/Partials/AlignItemsPanel.vala:58
-msgid "Align Bottom"
-msgstr "محاذة للأسفل"
-
-#: Layouts/Partials/Artboard.vala:144 Layouts/Partials/Artboard.vala:487
-#: Layouts/Partials/Layer.vala:139 Layouts/Partials/Layer.vala:687
-msgid "Lock Layer"
-msgstr "قفل الطبقة"
-
-#: Layouts/Partials/Artboard.vala:155 Layouts/Partials/Artboard.vala:529
-#: Layouts/Partials/Layer.vala:156 Layouts/Partials/Layer.vala:729
-msgid "Hide Layer"
-msgstr "اخفاء الطبقة"
-
-#: Layouts/Partials/Artboard.vala:487 Layouts/Partials/Layer.vala:687
-msgid "Unlock Layer"
-msgstr "فك قفل الطبقة"
-
-#: Layouts/Partials/Artboard.vala:529 Layouts/Partials/Layer.vala:729
-msgid "Show Layer"
-msgstr "اظهار الطبقة"
-
-#: Layouts/Partials/BorderItem.vala:121
-msgid "Choose border color"
-msgstr "اختر لون الحدود"
-
-#: Layouts/Partials/BorderItem.vala:176 Layouts/Partials/FillItem.vala:178
-msgid "Pick color"
-msgstr "اختر لون"
-
-#: Layouts/Partials/BorderItem.vala:191
-msgid "Remove border"
-msgstr "ازالة الحدود"
-
-#: Layouts/Partials/BorderItem.vala:275
-msgid "Show border"
-msgstr "اظهار الحدود"
-
-#: Layouts/Partials/BorderItem.vala:279
-msgid "Hide border"
-msgstr "اخفاء الحدود"
-
-#: Layouts/Partials/BorderRadiusPanel.vala:86
-msgid "Style"
-msgstr "النمط"
-
-#: Layouts/Partials/BorderRadiusPanel.vala:103
-msgid "Border Radius"
-msgstr "استدارة الحدود"
-
-#: Layouts/Partials/BorderRadiusPanel.vala:137
-msgid "Border radius options"
-msgstr "خيارات استدارة الحدود"
-
-#: Layouts/Partials/BorderRadiusPanel.vala:199
-msgid "Autoscale Corners"
-msgstr "حجم تلقائي للزوايا"
-
-#: Layouts/Partials/BorderRadiusPanel.vala:208
-msgid "Uniform Corners"
-msgstr "توحيد الزوايا"
-
-#: Layouts/Partials/BordersPanel.vala:53
-msgid "Borders"
-msgstr "الحدود"
-
-#: Layouts/Partials/BordersPanel.vala:64
-msgid "Add border"
-msgstr "اضافة حد"
-
-#: Layouts/Partials/FillItem.vala:114
-msgid "Choose fill color"
-msgstr "اختر لون الملء"
-
-#: Layouts/Partials/FillItem.vala:193
-msgid "Remove fill color"
-msgstr "ازالة لون الملء"
-
-#: Layouts/Partials/FillItem.vala:277
-msgid "Show fill color"
-msgstr "أظهار لون الملء"
-
-#: Layouts/Partials/FillItem.vala:281
-msgid "Hide fill color"
-msgstr "اخفاء لون الملئ"
-
-#: Layouts/Partials/FillsPanel.vala:54
-msgid "Fills"
-msgstr "التعبئات"
-
-#: Layouts/Partials/FillsPanel.vala:65
-msgid "Add fill color"
-msgstr "اضف لون ملئ"
-
-#: Layouts/Partials/TransformPanel.vala:96
-msgid "X"
-msgstr "س"
-
-#: Layouts/Partials/TransformPanel.vala:96
-msgid "Horizontal position"
-msgstr "الموقع الأفقي"
-
-#: Layouts/Partials/TransformPanel.vala:98
-msgid "Y"
-msgstr "ص"
-
-#: Layouts/Partials/TransformPanel.vala:98
-msgid "Vertical position"
-msgstr "الموقع العمودي"
-
-#: Layouts/Partials/TransformPanel.vala:100
-msgid "W"
-msgstr "ع"
-
-#: Layouts/Partials/TransformPanel.vala:100
-msgid "Width"
-msgstr "العرض"
-
-#: Layouts/Partials/TransformPanel.vala:102
-msgid "H"
-msgstr "ط"
-
-#: Layouts/Partials/TransformPanel.vala:102
-msgid "Height"
-msgstr "الطول"
-
-#: Layouts/Partials/TransformPanel.vala:107
-msgid "Lock Ratio"
-msgstr "قفل النسبة"
-
-#: Layouts/Partials/TransformPanel.vala:114
-msgid "R"
-msgstr "ر"
-
-#: Layouts/Partials/TransformPanel.vala:114
-msgid "Rotation degrees"
-msgstr "درجات التدوير"
-
-#: Layouts/Partials/TransformPanel.vala:126
-msgid "Flip Horizontally"
-msgstr "قلب افقي"
-
-#: Layouts/Partials/TransformPanel.vala:137
-msgid "Flip Vertically"
-msgstr "قلب عمودي"
-
-#: Layouts/Partials/TransformPanel.vala:165
-msgid "Position"
-msgstr "الموقع"
-
-#: Layouts/Partials/TransformPanel.vala:169
-msgid "Size"
-msgstr "الحجم"
-
-#: Layouts/Partials/TransformPanel.vala:178
-msgid "Opacity"
-msgstr "الشفافية"
-
-#: Layouts/RightSideBar.vala:111
-msgid "Search Layer"
-msgstr "البحث عن طبقة"
-
-#: Lib/Managers/ExportManager.vala:192 Lib/Managers/ExportManager.vala:219
-msgid "Generating preview, please wait…"
-msgstr "تكوين العرض، الرجاء الانتظار..."
-
-#: Lib/Managers/ExportManager.vala:313
-#, c-format
-msgid "Untitled %i"
-msgstr "بدون عنوان %i"
-
-#: Lib/Managers/ExportManager.vala:484
-msgid "Exporting images…"
-msgstr "تصدير الصور..."
-
-#: Partials/ExportWidget.vala:117
-#, c-format
-msgid "%i × %i px · %s"
-msgstr "%i × %i بكسل · %s"
-
-#: Partials/ExportWidget.vala:124
-msgid "Fetching image size…"
-msgstr "جاري احضار حجم الصورة..."
-
-#: Partials/ZoomButton.vala:49
-msgid "Zoom Out"
-msgstr "تصغير"
-
-#: Partials/ZoomButton.vala:55
-msgid "Reset Zoom"
-msgstr "اعادة تعيين التكبير"
-
-#: Partials/ZoomButton.vala:62
-msgid "Zoom In"
-msgstr "تكبير"
-
-#: Partials/ZoomButton.vala:68
-msgid "Zoom"
-msgstr "تكبير"
-
-#: Services/ActionManager.vala:217
-msgid "No recently opened file available!"
-msgstr "لا يوجد ملف مفتوح مؤخراً!"
-
-#: Services/ActionManager.vala:236
-msgid "No second most recently opened file available!"
-msgstr "لا يوجد ملف ثاني مفتوح مؤخراً!"
-
-#: Services/ActionManager.vala:255
-msgid "No third most recently opened file available!"
-msgstr "لا يوجد ملف ثالث مفتوح مؤخراً!"
-
-#: Services/ActionManager.vala:293
-msgid "Nothing selected to export!"
-msgstr "لم يتم تحديد شيء لتصديره!"
-
-#: Services/ActionManager.vala:302
-msgid "Export of Artboards currently unavailable…sorry 😑️"
-msgstr "تصدير المساحات الفنية حاليا غير متوف...آسف 😑️"
-
-#: Services/ActionManager.vala:373
-msgid "Choose image file"
-msgstr "اختر ملف صورة"
-
-#: Services/ActionManager.vala:373
-msgid "Select"
-msgstr "اختر"
-
-#: Services/ActionManager.vala:373
-msgid "Close"
-msgstr "اغلاق"
-
-#: Services/ActionManager.vala:442
-#, c-format
-msgid "Error! .%s files are not supported!"
-msgstr "خطأ . ملفات %s غير مدعومة!"
-
-#: Window.vala:121
-msgid "Are you sure you want to quit?"
-msgstr "هل أنت متأكد انك تريد الخروج؟"
-
-#: Window.vala:122
-msgid "All unsaved data will be lost and impossible to recover."
-msgstr "كل البيانات التي لم يتم حفظها ستفقد ويستحيل استعادتها."
-
-#: Window.vala:124
-msgid "Quit without saving!"
-msgstr "الخروج دون حفظ!"
-
-#: Window.vala:125
-msgid "Save file"
-msgstr "حفظ ملف "
diff --git a/po/as.po b/po/as.po
deleted file mode 100644
index 7d7bf5d53..000000000
--- a/po/as.po
+++ /dev/null
@@ -1,4 +0,0 @@
-msgid ""
-msgstr ""
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
diff --git a/po/ast.po b/po/ast.po
deleted file mode 100644
index 7d7bf5d53..000000000
--- a/po/ast.po
+++ /dev/null
@@ -1,4 +0,0 @@
-msgid ""
-msgstr ""
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
diff --git a/po/av.po b/po/av.po
deleted file mode 100644
index 7d7bf5d53..000000000
--- a/po/av.po
+++ /dev/null
@@ -1,4 +0,0 @@
-msgid ""
-msgstr ""
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
diff --git a/po/ay.po b/po/ay.po
deleted file mode 100644
index 7d7bf5d53..000000000
--- a/po/ay.po
+++ /dev/null
@@ -1,4 +0,0 @@
-msgid ""
-msgstr ""
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
diff --git a/po/az.po b/po/az.po
deleted file mode 100644
index 7d7bf5d53..000000000
--- a/po/az.po
+++ /dev/null
@@ -1,4 +0,0 @@
-msgid ""
-msgstr ""
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
diff --git a/po/ba.po b/po/ba.po
deleted file mode 100644
index 7d7bf5d53..000000000
--- a/po/ba.po
+++ /dev/null
@@ -1,4 +0,0 @@
-msgid ""
-msgstr ""
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
diff --git a/po/be.po b/po/be.po
deleted file mode 100644
index 6188ef853..000000000
--- a/po/be.po
+++ /dev/null
@@ -1,5 +0,0 @@
-msgid ""
-msgstr ""
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
-"Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n"
diff --git a/po/bg.po b/po/bg.po
deleted file mode 100644
index ca301d2fd..000000000
--- a/po/bg.po
+++ /dev/null
@@ -1,5 +0,0 @@
-msgid ""
-msgstr ""
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
-"Plural-Forms: nplurals=2; plural=n != 1;\n"
diff --git a/po/bh.po b/po/bh.po
deleted file mode 100644
index 7d7bf5d53..000000000
--- a/po/bh.po
+++ /dev/null
@@ -1,4 +0,0 @@
-msgid ""
-msgstr ""
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
diff --git a/po/bi.po b/po/bi.po
deleted file mode 100644
index 7d7bf5d53..000000000
--- a/po/bi.po
+++ /dev/null
@@ -1,4 +0,0 @@
-msgid ""
-msgstr ""
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
diff --git a/po/bm.po b/po/bm.po
deleted file mode 100644
index 7d7bf5d53..000000000
--- a/po/bm.po
+++ /dev/null
@@ -1,4 +0,0 @@
-msgid ""
-msgstr ""
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
diff --git a/po/bn.po b/po/bn.po
deleted file mode 100644
index 7d7bf5d53..000000000
--- a/po/bn.po
+++ /dev/null
@@ -1,4 +0,0 @@
-msgid ""
-msgstr ""
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
diff --git a/po/bo.po b/po/bo.po
deleted file mode 100644
index 7d7bf5d53..000000000
--- a/po/bo.po
+++ /dev/null
@@ -1,4 +0,0 @@
-msgid ""
-msgstr ""
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
diff --git a/po/br.po b/po/br.po
deleted file mode 100644
index 7d7bf5d53..000000000
--- a/po/br.po
+++ /dev/null
@@ -1,4 +0,0 @@
-msgid ""
-msgstr ""
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
diff --git a/po/bs.po b/po/bs.po
deleted file mode 100644
index 7d7bf5d53..000000000
--- a/po/bs.po
+++ /dev/null
@@ -1,4 +0,0 @@
-msgid ""
-msgstr ""
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
diff --git a/po/ca.po b/po/ca.po
deleted file mode 100644
index 7d7bf5d53..000000000
--- a/po/ca.po
+++ /dev/null
@@ -1,4 +0,0 @@
-msgid ""
-msgstr ""
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
diff --git a/po/ce.po b/po/ce.po
deleted file mode 100644
index 7d7bf5d53..000000000
--- a/po/ce.po
+++ /dev/null
@@ -1,4 +0,0 @@
-msgid ""
-msgstr ""
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
diff --git a/po/ch.po b/po/ch.po
deleted file mode 100644
index 7d7bf5d53..000000000
--- a/po/ch.po
+++ /dev/null
@@ -1,4 +0,0 @@
-msgid ""
-msgstr ""
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
diff --git a/po/ckb.po b/po/ckb.po
deleted file mode 100644
index 7d7bf5d53..000000000
--- a/po/ckb.po
+++ /dev/null
@@ -1,4 +0,0 @@
-msgid ""
-msgstr ""
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
diff --git a/po/co.po b/po/co.po
deleted file mode 100644
index 7d7bf5d53..000000000
--- a/po/co.po
+++ /dev/null
@@ -1,4 +0,0 @@
-msgid ""
-msgstr ""
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
diff --git a/po/cr.po b/po/cr.po
deleted file mode 100644
index 7d7bf5d53..000000000
--- a/po/cr.po
+++ /dev/null
@@ -1,4 +0,0 @@
-msgid ""
-msgstr ""
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
diff --git a/po/cs.po b/po/cs.po
deleted file mode 100644
index fb0b545a5..000000000
--- a/po/cs.po
+++ /dev/null
@@ -1,5 +0,0 @@
-msgid ""
-msgstr ""
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
-"Plural-Forms: nplurals=3; plural=(n==1) ? 0 : (n>=2 && n<=4) ? 1 : 2;\n"
diff --git a/po/cu.po b/po/cu.po
deleted file mode 100644
index 7d7bf5d53..000000000
--- a/po/cu.po
+++ /dev/null
@@ -1,4 +0,0 @@
-msgid ""
-msgstr ""
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
diff --git a/po/cv.po b/po/cv.po
deleted file mode 100644
index 7d7bf5d53..000000000
--- a/po/cv.po
+++ /dev/null
@@ -1,4 +0,0 @@
-msgid ""
-msgstr ""
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
diff --git a/po/cy.po b/po/cy.po
deleted file mode 100644
index 7d7bf5d53..000000000
--- a/po/cy.po
+++ /dev/null
@@ -1,4 +0,0 @@
-msgid ""
-msgstr ""
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
diff --git a/po/da.po b/po/da.po
deleted file mode 100644
index 7d7bf5d53..000000000
--- a/po/da.po
+++ /dev/null
@@ -1,4 +0,0 @@
-msgid ""
-msgstr ""
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
diff --git a/po/de.po b/po/de.po
deleted file mode 100644
index ba16a987f..000000000
--- a/po/de.po
+++ /dev/null
@@ -1,672 +0,0 @@
-#
-# XP312 < >, 2020.
-#
-msgid ""
-msgstr ""
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
-"Plural-Forms: nplurals=2; plural=(n != 1)\n"
-"Project-Id-Version: unnamed project\n"
-"Last-Translator: XP312 < >\n"
-"Language-Team: German < >\n"
-"Language: de\n"
-"Content-Transfer-Encoding: 8bit\n"
-"PO-Revision-Date: 2020-09-03 14:38+0200\n"
-"X-Generator: Gtranslator 3.36.0\n"
-
-#: Dialogs/ExportDialog.vala:151
-msgid "Export to:"
-msgstr "Exportiere nach:"
-
-#: Dialogs/ExportDialog.vala:157
-msgid "Select Folder"
-msgstr "Ordner auswählen"
-
-#: Dialogs/ExportDialog.vala:166
-msgid "Format:"
-msgstr "Format:"
-
-#: Dialogs/ExportDialog.vala:180
-msgid "Quality:"
-msgstr "Qualität:"
-
-#: Dialogs/ExportDialog.vala:192
-msgid "Compression:"
-msgstr "Kompression:"
-
-#: Dialogs/ExportDialog.vala:206
-msgid "Transparency:"
-msgstr "Transparenz:"
-
-#: Dialogs/ExportDialog.vala:219
-msgid "Scale:"
-msgstr "Größe:"
-
-#: Dialogs/ExportDialog.vala:243 FileFormat/FileManager.vala:49
-#: FileFormat/FileManager.vala:105
-msgid "Cancel"
-msgstr "Abbrechen"
-
-#: Dialogs/ExportDialog.vala:250 Dialogs/ShortcutsDialog.vala:63
-#: Layouts/HeaderBar.vala:112
-msgid "Export"
-msgstr "Exportieren"
-
-#: Dialogs/ReleaseDialog.vala:47 Dialogs/SettingsDialog.vala:217
-msgid ""
-"WARNING!\n"
-"Akira is still under development and not ready for production. Missing "
-"features, random bugs, and black holes opening in your kitchen are to be "
-"expected."
-msgstr ""
-"ACHTUNG:\n"
-"Akira ist noch in Entwicklung und deshalb noch nicht für die Verwendung in der Produktion geeignet."
-"Fehlende Funktionen, Bugs und schwarze Löcher die sich in der Küche öffnen "
-"sind zu erwarten."
-
-#: Dialogs/ReleaseDialog.vala:100 Dialogs/SettingsDialog.vala:249
-msgid "Make a Donation"
-msgstr "Für das Projekt spenden"
-
-#: Dialogs/ReleaseDialog.vala:109 Dialogs/SettingsDialog.vala:258
-msgid "Suggest Translations"
-msgstr "Übersetzungen vorschlagen"
-
-#: Dialogs/ReleaseDialog.vala:118 Dialogs/SettingsDialog.vala:267
-msgid "Report a Problem"
-msgstr "Fehler melden"
-
-#: Dialogs/SettingsDialog.vala:40
-msgid "Preferences"
-msgstr "Einstellungen"
-
-#: Dialogs/SettingsDialog.vala:50 Dialogs/SettingsDialog.vala:73
-#: Dialogs/ShortcutsDialog.vala:45
-msgid "General"
-msgstr "Allgemein"
-
-#: Dialogs/SettingsDialog.vala:51 Dialogs/SettingsDialog.vala:86
-msgid "Interface"
-msgstr "Oberfläche"
-
-#: Dialogs/SettingsDialog.vala:52 Layouts/HeaderBar.vala:280
-msgid "Shapes"
-msgstr "Formen"
-
-#: Dialogs/SettingsDialog.vala:53
-msgid "About"
-msgstr "Über"
-
-#: Dialogs/SettingsDialog.vala:74
-msgid "Auto Reopen Latest File:"
-msgstr "Automatisch die letzte Datei erneut öffnen:"
-
-#: Dialogs/SettingsDialog.vala:88
-msgid "Use Dark Theme:"
-msgstr "Schwarzes Thema nutzen:"
-
-#: Dialogs/SettingsDialog.vala:92
-msgid "Invert Panels Order:"
-msgstr "Reihenfolge der Panels umkehren:"
-
-#: Dialogs/SettingsDialog.vala:96
-msgid "Restart application to apply this change."
-msgstr "Anwendungen neustarten um Änderungen zu übernehmen."
-
-#: Dialogs/SettingsDialog.vala:100
-msgid "ToolBar Style"
-msgstr "Werkzeugleistenstil"
-
-#: Dialogs/SettingsDialog.vala:102
-msgid "Show Button Labels:"
-msgstr "Knopfbeschreibungen anzeigen:"
-
-#: Dialogs/SettingsDialog.vala:106
-msgid "Use Symbolic Icons:"
-msgstr "Symbolische Icons nutzen:"
-
-#: Dialogs/SettingsDialog.vala:129
-msgid "Default Colors"
-msgstr "Standardfarben"
-
-#: Dialogs/SettingsDialog.vala:131
-msgid "Define the default style used when creating a new shape."
-msgstr "Definierung des Standardaussehens einer neuen Form."
-
-#: Dialogs/SettingsDialog.vala:136
-msgid "Fill Color:"
-msgstr "Füllfarbe:"
-
-#: Dialogs/SettingsDialog.vala:157
-msgid "Enable Border Style:"
-msgstr "Aktiviere Ränderstil:"
-
-#: Dialogs/SettingsDialog.vala:160
-msgid "Border Color:"
-msgstr "Ränder Farbe:"
-
-#: Dialogs/SettingsDialog.vala:181
-msgid "Border Width:"
-msgstr "Ränder Breite:"
-
-#: Dialogs/SettingsDialog.vala:209
-msgid "The Linux Design Tool"
-msgstr "Das Linux Designwerkzeug"
-
-#: Dialogs/SettingsDialog.vala:226
-msgid "Thanks to our awesome supporters!"
-msgstr "Danke an unsere tollen Unterstützer!"
-
-#: Dialogs/SettingsDialog.vala:231
-msgid "View the list of supporters"
-msgstr "Liste aller Unterstützer"
-
-#: Dialogs/ShortcutsDialog.vala:46
-msgid "New window:"
-msgstr "Neues Fenster:"
-
-#: Dialogs/ShortcutsDialog.vala:48
-msgid "Preferences:"
-msgstr "Einstellungen:"
-
-#: Dialogs/ShortcutsDialog.vala:50
-msgid "Quit:"
-msgstr "Beenden:"
-
-#: Dialogs/ShortcutsDialog.vala:52
-msgid "Presentation mode:"
-msgstr "Präsentationsmodus:"
-
-#: Dialogs/ShortcutsDialog.vala:55
-msgid "File"
-msgstr "Datei"
-
-#: Dialogs/ShortcutsDialog.vala:56
-msgid "Open:"
-msgstr "Öffnen:"
-
-#: Dialogs/ShortcutsDialog.vala:58
-msgid "Save:"
-msgstr "Speichern:"
-
-#: Dialogs/ShortcutsDialog.vala:60
-msgid "Save as:"
-msgstr "Speichern als:"
-
-#: Dialogs/ShortcutsDialog.vala:64
-msgid "Export artboards:"
-msgstr "Zeichenbrett exportieren:"
-
-#: Dialogs/ShortcutsDialog.vala:66
-msgid "Export selection:"
-msgstr "Auswahl exportieren:"
-
-#: Dialogs/ShortcutsDialog.vala:68
-msgid "Highlight area to export:"
-msgstr "Bereich zum exportieren auswählen:"
-
-#: Dialogs/ShortcutsDialog.vala:77
-msgid "Canvas"
-msgstr "Leinwand"
-
-#: Dialogs/ShortcutsDialog.vala:78
-msgid "Zoom in:"
-msgstr "Vergrößern"
-
-#: Dialogs/ShortcutsDialog.vala:80
-msgid "Zoom out:"
-msgstr "Verkleinern"
-
-#: Dialogs/ShortcutsDialog.vala:82
-msgid "Zoom reset:"
-msgstr "Zoom zurücksetzen"
-
-#: Dialogs/ShortcutsDialog.vala:85
-msgid "Item creation"
-msgstr "Objekterstellung"
-
-#: Dialogs/ShortcutsDialog.vala:86
-msgid "Artboard:"
-msgstr "Zeichenbrett:"
-
-#: Dialogs/ShortcutsDialog.vala:88
-msgid "Rectangle:"
-msgstr "Rechteck:"
-
-#: Dialogs/ShortcutsDialog.vala:90
-msgid "Ellipse:"
-msgstr "Ellipse:"
-
-#: Dialogs/ShortcutsDialog.vala:92
-msgid "Text:"
-msgstr "Text:"
-
-#: Dialogs/ShortcutsDialog.vala:94
-msgid "Image:"
-msgstr "Foto:"
-
-#: Dialogs/ShortcutsDialog.vala:97 Layouts/Partials/TransformPanel.vala:174
-msgid "Transform"
-msgstr "Transformieren"
-
-#: Dialogs/ShortcutsDialog.vala:98
-msgid "Raise selection:"
-msgstr "Auswahl erhöhen:"
-
-#: Dialogs/ShortcutsDialog.vala:100
-msgid "Lower selection:"
-msgstr "Auswahl verringern:"
-
-#: Dialogs/ShortcutsDialog.vala:102
-msgid "Raise selection to top:"
-msgstr "Auswahl nach oben erhöhen:"
-
-#: Dialogs/ShortcutsDialog.vala:104
-msgid "Lower selection to bottom:"
-msgstr "Auswahl nach unten verringern:"
-
-#: Dialogs/ShortcutsDialog.vala:106
-msgid "Flip horizontally:"
-msgstr "Horizontal drehen:"
-
-#: Dialogs/ShortcutsDialog.vala:108
-msgid "Flip vertically:"
-msgstr "Vertikal drehen:"
-
-#: FileFormat/FileManager.vala:46
-msgid "Save Akira file"
-msgstr "Akira-Datei speichern"
-
-#: FileFormat/FileManager.vala:48 Layouts/HeaderBar.vala:190
-msgid "Save"
-msgstr "Speichern"
-
-#: FileFormat/FileManager.vala:71
-msgid "Akira files"
-msgstr "Akira-Dateien"
-
-#: FileFormat/FileManager.vala:76
-msgid "All files"
-msgstr "Alle Dateien"
-
-#: FileFormat/FileManager.vala:103
-msgid "Open Akira file"
-msgstr "Akira-Datei öffnen"
-
-#: FileFormat/FileManager.vala:105 Layouts/HeaderBar.vala:170
-msgid "Open"
-msgstr "Öffnen"
-
-#: Layouts/HeaderBar.vala:69 Lib/Managers/ExportManager.vala:296
-msgid "Untitled"
-msgstr "Nicht gespeichert"
-
-#: Layouts/HeaderBar.vala:71
-msgid "Menu"
-msgstr "Menü"
-
-#: Layouts/HeaderBar.vala:75
-msgid "Insert"
-msgstr "Einfügen"
-
-#: Layouts/HeaderBar.vala:82
-msgid "Group"
-msgstr "Gruppieren"
-
-#: Layouts/HeaderBar.vala:84
-msgid "Ungroup"
-msgstr "Gruppierung aufheben"
-
-#: Layouts/HeaderBar.vala:87
-msgid "Up"
-msgstr "Hoch"
-
-#: Layouts/HeaderBar.vala:92
-msgid "Down"
-msgstr "Runter"
-
-#: Layouts/HeaderBar.vala:97
-msgid "Top"
-msgstr "Oben"
-
-#: Layouts/HeaderBar.vala:102
-msgid "Bottom"
-msgstr "Unten"
-
-#: Layouts/HeaderBar.vala:107
-msgid "Settings"
-msgstr "Einstellungen"
-
-# ?
-#: Layouts/HeaderBar.vala:118
-#, fuzzy
-msgid "Difference"
-msgstr "Differenz"
-
-#: Layouts/HeaderBar.vala:120
-#, fuzzy
-msgid "Exclusion"
-msgstr "Ausgrenzen"
-
-#: Layouts/HeaderBar.vala:122
-#, fuzzy
-msgid "Intersect"
-msgstr "Überschneiden"
-
-#: Layouts/HeaderBar.vala:124
-msgid "Union"
-msgstr "Verbinden"
-
-#: Layouts/HeaderBar.vala:161
-msgid "New Window"
-msgstr "Neues Fenster"
-
-#: Layouts/HeaderBar.vala:182
-msgid "Open Recent"
-msgstr "Zuletzt geöffnet"
-
-#: Layouts/HeaderBar.vala:195
-msgid "Save As"
-msgstr "Speichern als"
-
-#: Layouts/HeaderBar.vala:204
-msgid "Quit"
-msgstr "Schließen"
-
-#: Layouts/HeaderBar.vala:237
-msgid "Artboard"
-msgstr "Zeichenbrett"
-
-#: Layouts/HeaderBar.vala:254
-msgid "Add Items"
-msgstr "Objekt hinzufügen"
-
-#: Layouts/HeaderBar.vala:262
-msgid "Rectangle"
-msgstr "Rechteck"
-
-#: Layouts/HeaderBar.vala:268
-msgid "Ellipse"
-msgstr "Ellipse"
-
-#: Layouts/HeaderBar.vala:286
-msgid "Vector"
-msgstr "Vektor"
-
-#: Layouts/HeaderBar.vala:288
-msgid "Pencil"
-msgstr "Stift"
-
-#: Layouts/HeaderBar.vala:291
-msgid "Text"
-msgstr "Text"
-
-#: Layouts/HeaderBar.vala:297
-msgid "Image"
-msgstr "Bild"
-
-#: Layouts/HeaderBar.vala:330
-msgid "Export Current Selection"
-msgstr "Aktuelle Auswahl exportieren"
-
-#: Layouts/HeaderBar.vala:336
-msgid "Export Artboards"
-msgstr "Aktuelles Zeichenbrett exportieren"
-
-#: Layouts/HeaderBar.vala:345
-msgid "Highlight Area to Export"
-msgstr "Bereich zum Exportieren auswählen"
-
-#: Layouts/HeaderBar.vala:391
-msgid "Main Menu"
-msgstr "Hauptmenü"
-
-#: Layouts/HeaderBar.vala:468 Services/ActionManager.vala:218
-#: Services/ActionManager.vala:237 Services/ActionManager.vala:256
-#, c-format
-msgid "Unable to open file at '%s'"
-msgstr "Konnte Datei \"%s\" nicht öffnen"
-
-#: Layouts/MainCanvas.vala:52
-msgid "Button was pressed!"
-msgstr "Knopf wurde gedrückt!"
-
-#: Layouts/MainCanvas.vala:160
-msgid "Export completed!"
-msgstr "Export abgeschlossen!"
-
-#: Layouts/Partials/AlignItemsPanel.vala:48
-#, fuzzy
-msgid "Distribute Horizontally"
-msgstr "Horizontall verteilen"
-
-#: Layouts/Partials/AlignItemsPanel.vala:50
-#, fuzzy
-msgid "Distribute Vertically"
-msgstr "Vertikal verteilen"
-
-#: Layouts/Partials/AlignItemsPanel.vala:52
-msgid "Align Left"
-msgstr "Links ausrichten"
-
-#: Layouts/Partials/AlignItemsPanel.vala:53
-msgid "Align Center"
-msgstr "Zentral ausrichten"
-
-#: Layouts/Partials/AlignItemsPanel.vala:54
-msgid "Align Right"
-msgstr "Rechts ausrichten"
-
-#: Layouts/Partials/AlignItemsPanel.vala:56
-msgid "Align Top"
-msgstr "Nach oben ausrichten"
-
-#: Layouts/Partials/AlignItemsPanel.vala:57
-msgid "Align Middle"
-msgstr "Mittig ausrichten"
-
-#: Layouts/Partials/AlignItemsPanel.vala:58
-msgid "Align Bottom"
-msgstr "Nach unten ausrichten"
-
-#: Layouts/Partials/Artboard.vala:144 Layouts/Partials/Artboard.vala:487
-#: Layouts/Partials/Layer.vala:139 Layouts/Partials/Layer.vala:687
-msgid "Lock Layer"
-msgstr "Ebene sperren"
-
-#: Layouts/Partials/Artboard.vala:155 Layouts/Partials/Artboard.vala:529
-#: Layouts/Partials/Layer.vala:156 Layouts/Partials/Layer.vala:729
-msgid "Hide Layer"
-msgstr "Ebene verstecken"
-
-#: Layouts/Partials/Artboard.vala:487 Layouts/Partials/Layer.vala:687
-msgid "Unlock Layer"
-msgstr "Ebene entsperren"
-
-#: Layouts/Partials/Artboard.vala:529 Layouts/Partials/Layer.vala:729
-msgid "Show Layer"
-msgstr "Ebene anzeigen"
-
-#: Layouts/Partials/BorderRadiusPanel.vala:86
-msgid "Style"
-msgstr "Stil"
-
-#: Layouts/Partials/BorderRadiusPanel.vala:103
-msgid "Border Radius"
-msgstr "Randradius"
-
-#: Layouts/Partials/BorderRadiusPanel.vala:198
-msgid "Autoscale Corners"
-msgstr "Ecken Automatisch skallieren"
-
-#: Layouts/Partials/BorderRadiusPanel.vala:207
-msgid "Uniform Corners"
-msgstr "Ecken angleichen"
-
-#: Layouts/Partials/BordersPanel.vala:53
-msgid "Borders"
-msgstr "Ränder"
-
-#: Layouts/Partials/FillsPanel.vala:54
-msgid "Fills"
-msgstr "Füllungen"
-
-#: Layouts/Partials/TransformPanel.vala:96
-msgid "X"
-msgstr "X"
-
-#: Layouts/Partials/TransformPanel.vala:96
-msgid "Horizontal position"
-msgstr "Horizontale Position"
-
-#: Layouts/Partials/TransformPanel.vala:98
-msgid "Y"
-msgstr "Y"
-
-#: Layouts/Partials/TransformPanel.vala:98
-msgid "Vertical position"
-msgstr "Vertikale Position"
-
-#: Layouts/Partials/TransformPanel.vala:100
-msgid "W"
-msgstr "W"
-
-#: Layouts/Partials/TransformPanel.vala:100
-msgid "Width"
-msgstr "Breite"
-
-#: Layouts/Partials/TransformPanel.vala:102
-msgid "H"
-msgstr "H"
-
-#: Layouts/Partials/TransformPanel.vala:102
-msgid "Height"
-msgstr "Höhe"
-
-#: Layouts/Partials/TransformPanel.vala:107
-msgid "Lock Ratio"
-msgstr "Rotation sperren"
-
-#: Layouts/Partials/TransformPanel.vala:114
-msgid "R"
-msgstr "R"
-
-#: Layouts/Partials/TransformPanel.vala:114
-#, fuzzy
-msgid "Rotation degrees"
-msgstr "Rotationsgrad"
-
-#: Layouts/Partials/TransformPanel.vala:126
-msgid "Flip Horizontally"
-msgstr "Horizontahl drehen"
-
-#: Layouts/Partials/TransformPanel.vala:137
-msgid "Flip Vertically"
-msgstr "Vertikal drehen"
-
-#: Layouts/Partials/TransformPanel.vala:165
-msgid "Position"
-msgstr "Position"
-
-#: Layouts/Partials/TransformPanel.vala:169
-msgid "Size"
-msgstr "Größe"
-
-#: Layouts/Partials/TransformPanel.vala:178
-msgid "Opacity"
-msgstr "Deckkraft"
-
-#: Layouts/RightSideBar.vala:111
-msgid "Search Layer"
-msgstr "Ebenensuche"
-
-#: Lib/Managers/ExportManager.vala:192 Lib/Managers/ExportManager.vala:219
-msgid "Generating preview, please wait…"
-msgstr "Vorschau wird generiert, bitte warten..."
-
-#: Lib/Managers/ExportManager.vala:313
-#, c-format
-msgid "Untitled %i"
-msgstr "Unbenannt %i"
-
-#: Lib/Managers/ExportManager.vala:484
-msgid "Exporting images…"
-msgstr "Exportiere Bilder..."
-
-#: Partials/ExportWidget.vala:117
-#, c-format
-msgid "%i × %i px · %s"
-msgstr "%i × %i px · %s"
-
-#: Partials/ExportWidget.vala:124
-msgid "Fetching image size…"
-msgstr "Frage Bildgröße ab..."
-
-#: Partials/ZoomButton.vala:49
-msgid "Zoom Out"
-msgstr "Verkleinern"
-
-#: Partials/ZoomButton.vala:55
-msgid "Reset Zoom"
-msgstr "Zoom zurücksetzen"
-
-#: Partials/ZoomButton.vala:62
-msgid "Zoom In"
-msgstr "Vergrößern"
-
-#: Partials/ZoomButton.vala:68
-msgid "Zoom"
-msgstr "Zoom"
-
-#: Services/ActionManager.vala:211
-msgid "No recently opened file available!"
-msgstr "Keine zuletzt geöffnete Datei vorhanden!"
-
-#: Services/ActionManager.vala:230
-msgid "No second most recently opened file available!"
-msgstr "Keine zweit zuletzt geöffnete Datei vorhanden!"
-
-#: Services/ActionManager.vala:249
-msgid "No third most recently opened file available!"
-msgstr "Keine dritt zuletzt geöffnete Datei vorhanden!"
-
-#: Services/ActionManager.vala:287
-msgid "Nothing selected to export!"
-msgstr "Nichts zum Exportieren ausgewählt!"
-
-#: Services/ActionManager.vala:296
-msgid "Export of Artboards currently unavailable…sorry 😑️"
-msgstr "Das Exportieren von Zeichenbrettern ist momentan leider nicht möglich… 😑️"
-
-#: Services/ActionManager.vala:363
-msgid "Choose image file"
-msgstr "Bilddatei auswählen"
-
-#: Services/ActionManager.vala:363
-msgid "Select"
-msgstr "Auswählen"
-
-#: Services/ActionManager.vala:363
-msgid "Close"
-msgstr "Schließen"
-
-#: Services/ActionManager.vala:432
-#, c-format
-msgid "Error! .%s files are not supported!"
-msgstr "Fehler: .%s Dateien werden nicht Unterstützt."
-
-#: Window.vala:119
-msgid "Are you sure you want to quit?"
-msgstr "Soll das Programm wirklich geschlossen werden?"
-
-#: Window.vala:120
-msgid "All unsaved data will be lost and impossible to recover."
-msgstr "Alle nicht gespeicherten Dateien gehen verloren und können nicht wiederhergestellt werden."
-
-#: Window.vala:122
-msgid "Quit without saving!"
-msgstr "Ohne speichern schließen!"
-
-#: Window.vala:123
-msgid "Save file"
-msgstr "Datei speichern"
diff --git a/po/dv.po b/po/dv.po
deleted file mode 100644
index 7d7bf5d53..000000000
--- a/po/dv.po
+++ /dev/null
@@ -1,4 +0,0 @@
-msgid ""
-msgstr ""
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
diff --git a/po/dz.po b/po/dz.po
deleted file mode 100644
index 7d7bf5d53..000000000
--- a/po/dz.po
+++ /dev/null
@@ -1,4 +0,0 @@
-msgid ""
-msgstr ""
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
diff --git a/po/ee.po b/po/ee.po
deleted file mode 100644
index 7d7bf5d53..000000000
--- a/po/ee.po
+++ /dev/null
@@ -1,4 +0,0 @@
-msgid ""
-msgstr ""
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
diff --git a/po/el.po b/po/el.po
deleted file mode 100644
index 7d7bf5d53..000000000
--- a/po/el.po
+++ /dev/null
@@ -1,4 +0,0 @@
-msgid ""
-msgstr ""
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
diff --git a/po/en_AU.po b/po/en_AU.po
deleted file mode 100644
index 7d7bf5d53..000000000
--- a/po/en_AU.po
+++ /dev/null
@@ -1,4 +0,0 @@
-msgid ""
-msgstr ""
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
diff --git a/po/en_CA.po b/po/en_CA.po
deleted file mode 100644
index 7d7bf5d53..000000000
--- a/po/en_CA.po
+++ /dev/null
@@ -1,4 +0,0 @@
-msgid ""
-msgstr ""
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
diff --git a/po/en_GB.po b/po/en_GB.po
deleted file mode 100644
index 7d7bf5d53..000000000
--- a/po/en_GB.po
+++ /dev/null
@@ -1,4 +0,0 @@
-msgid ""
-msgstr ""
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
diff --git a/po/eo.po b/po/eo.po
deleted file mode 100644
index ca301d2fd..000000000
--- a/po/eo.po
+++ /dev/null
@@ -1,5 +0,0 @@
-msgid ""
-msgstr ""
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
-"Plural-Forms: nplurals=2; plural=n != 1;\n"
diff --git a/po/es.po b/po/es.po
deleted file mode 100644
index e2249bc25..000000000
--- a/po/es.po
+++ /dev/null
@@ -1,666 +0,0 @@
-msgid ""
-msgstr ""
-"Project-Id-Version: \n"
-"POT-Creation-Date: 2020-08-12 22:06-0500\n"
-"PO-Revision-Date: \n"
-"Last-Translator: Adolfo Jayme Barrientos \n"
-"Language-Team: \n"
-"Language: es\n"
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
-"Content-Transfer-Encoding: 8bit\n"
-"Plural-Forms: nplurals=2; plural=n != 1;\n"
-"X-Generator: Poedit 2.4.1\n"
-"X-Poedit-Basepath: ../src\n"
-"X-Poedit-SearchPath-0: .\n"
-
-#: Dialogs/ExportDialog.vala:151
-msgid "Export to:"
-msgstr "Exportar en:"
-
-#: Dialogs/ExportDialog.vala:157
-msgid "Select Folder"
-msgstr "Seleccionar carpeta"
-
-#: Dialogs/ExportDialog.vala:166
-msgid "Format:"
-msgstr "Formato:"
-
-#: Dialogs/ExportDialog.vala:180
-msgid "Quality:"
-msgstr "Calidad:"
-
-#: Dialogs/ExportDialog.vala:192
-msgid "Compression:"
-msgstr "Compresión:"
-
-#: Dialogs/ExportDialog.vala:206
-msgid "Transparency:"
-msgstr "Transparencia:"
-
-#: Dialogs/ExportDialog.vala:219
-msgid "Scale:"
-msgstr "Escala:"
-
-#: Dialogs/ExportDialog.vala:243 FileFormat/FileManager.vala:49
-#: FileFormat/FileManager.vala:105
-msgid "Cancel"
-msgstr "Cancelar"
-
-#: Dialogs/ExportDialog.vala:250 Dialogs/ShortcutsDialog.vala:63
-#: Layouts/HeaderBar.vala:112
-msgid "Export"
-msgstr "Exportar"
-
-#: Dialogs/ReleaseDialog.vala:47 Dialogs/SettingsDialog.vala:217
-msgid ""
-"WARNING!\n"
-"Akira is still under development and not ready for production. Missing "
-"features, random bugs, and black holes opening in your kitchen are to be "
-"expected."
-msgstr ""
-"ATENCIÓN:\n"
-"Akira se encuentra en desarrollo y no está destinado a entornos de "
-"producción. Es de esperar que falten funciones y haya defectos inesperados."
-
-#: Dialogs/ReleaseDialog.vala:100 Dialogs/SettingsDialog.vala:249
-msgid "Make a Donation"
-msgstr "Donar"
-
-#: Dialogs/ReleaseDialog.vala:109 Dialogs/SettingsDialog.vala:258
-msgid "Suggest Translations"
-msgstr "Sugerir traducciones"
-
-#: Dialogs/ReleaseDialog.vala:118 Dialogs/SettingsDialog.vala:267
-msgid "Report a Problem"
-msgstr "Informar de un problema"
-
-#: Dialogs/SettingsDialog.vala:40
-msgid "Preferences"
-msgstr "Preferencias"
-
-#: Dialogs/SettingsDialog.vala:50 Dialogs/SettingsDialog.vala:73
-#: Dialogs/ShortcutsDialog.vala:45
-msgid "General"
-msgstr "Generales"
-
-#: Dialogs/SettingsDialog.vala:51 Dialogs/SettingsDialog.vala:86
-msgid "Interface"
-msgstr "Interfaz"
-
-#: Dialogs/SettingsDialog.vala:52 Layouts/HeaderBar.vala:280
-msgid "Shapes"
-msgstr "Formas"
-
-#: Dialogs/SettingsDialog.vala:53
-msgid "About"
-msgstr "Acerca de"
-
-#: Dialogs/SettingsDialog.vala:74
-msgid "Auto Reopen Latest File:"
-msgstr "Reabrir automáticamente archivo más reciente:"
-
-#: Dialogs/SettingsDialog.vala:88
-msgid "Use Dark Theme:"
-msgstr "Utilizar tema oscuro:"
-
-#: Dialogs/SettingsDialog.vala:92
-msgid "Invert Panels Order:"
-msgstr "Intercambiar posición de paneles:"
-
-#: Dialogs/SettingsDialog.vala:96
-msgid "Restart application to apply this change."
-msgstr "Reinicie la aplicación para aplicar el cambio."
-
-#: Dialogs/SettingsDialog.vala:100
-msgid "ToolBar Style"
-msgstr "Estilo de barra de herramientas"
-
-#: Dialogs/SettingsDialog.vala:102
-msgid "Show Button Labels:"
-msgstr "Mostrar etiquetas de botones:"
-
-#: Dialogs/SettingsDialog.vala:106
-msgid "Use Symbolic Icons:"
-msgstr "Utilizar iconos monocromáticos:"
-
-#: Dialogs/SettingsDialog.vala:129
-msgid "Default Colors"
-msgstr "Colores predeterminados"
-
-#: Dialogs/SettingsDialog.vala:131
-msgid "Define the default style used when creating a new shape."
-msgstr ""
-"Defina el estilo que se utilizará de manera predeterminada al crear formas."
-
-#: Dialogs/SettingsDialog.vala:136
-msgid "Fill Color:"
-msgstr "Color de relleno:"
-
-#: Dialogs/SettingsDialog.vala:157
-msgid "Enable Border Style:"
-msgstr "Activar estilo con borde:"
-
-#: Dialogs/SettingsDialog.vala:160
-msgid "Border Color:"
-msgstr "Color de borde:"
-
-#: Dialogs/SettingsDialog.vala:181
-msgid "Border Width:"
-msgstr "Anchura de borde:"
-
-#: Dialogs/SettingsDialog.vala:209
-msgid "The Linux Design Tool"
-msgstr "La herramienta de diseño para Linux"
-
-#: Dialogs/SettingsDialog.vala:226
-msgid "Thanks to our awesome supporters!"
-msgstr "¡Gracias a nuestros geniales partidarios!"
-
-#: Dialogs/SettingsDialog.vala:231
-msgid "View the list of supporters"
-msgstr "Ver lista de partidarios"
-
-#: Dialogs/ShortcutsDialog.vala:46
-msgid "New window:"
-msgstr "Ventana nueva:"
-
-#: Dialogs/ShortcutsDialog.vala:48
-msgid "Preferences:"
-msgstr "Preferencias:"
-
-#: Dialogs/ShortcutsDialog.vala:50
-msgid "Quit:"
-msgstr "Salir:"
-
-#: Dialogs/ShortcutsDialog.vala:52
-msgid "Presentation mode:"
-msgstr "Modo de presentación:"
-
-#: Dialogs/ShortcutsDialog.vala:55
-msgid "File"
-msgstr "Archivo"
-
-#: Dialogs/ShortcutsDialog.vala:56
-msgid "Open:"
-msgstr "Abrir:"
-
-#: Dialogs/ShortcutsDialog.vala:58
-msgid "Save:"
-msgstr "Guardar:"
-
-#: Dialogs/ShortcutsDialog.vala:60
-msgid "Save as:"
-msgstr "Guardar como:"
-
-#: Dialogs/ShortcutsDialog.vala:64
-msgid "Export artboards:"
-msgstr "Exportar mesas de trabajo:"
-
-#: Dialogs/ShortcutsDialog.vala:66
-msgid "Export selection:"
-msgstr "Exportar selección:"
-
-#: Dialogs/ShortcutsDialog.vala:68
-msgid "Highlight area to export:"
-msgstr "Resaltar área que exportar:"
-
-#: Dialogs/ShortcutsDialog.vala:77
-msgid "Canvas"
-msgstr "Lienzo"
-
-#: Dialogs/ShortcutsDialog.vala:78
-msgid "Zoom in:"
-msgstr "Acercar"
-
-#: Dialogs/ShortcutsDialog.vala:80
-msgid "Zoom out:"
-msgstr "Alejar"
-
-#: Dialogs/ShortcutsDialog.vala:82
-msgid "Zoom reset:"
-msgstr "Restablecer escala:"
-
-#: Dialogs/ShortcutsDialog.vala:85
-msgid "Item creation"
-msgstr "Creación de elemento"
-
-#: Dialogs/ShortcutsDialog.vala:86
-msgid "Artboard:"
-msgstr "Mesa de trabajo:"
-
-#: Dialogs/ShortcutsDialog.vala:88
-msgid "Rectangle:"
-msgstr "Rectángulo:"
-
-#: Dialogs/ShortcutsDialog.vala:90
-msgid "Ellipse:"
-msgstr "Elipse:"
-
-#: Dialogs/ShortcutsDialog.vala:92
-msgid "Text:"
-msgstr "Texto:"
-
-#: Dialogs/ShortcutsDialog.vala:94
-msgid "Image:"
-msgstr "Imagen:"
-
-#: Dialogs/ShortcutsDialog.vala:97 Layouts/Partials/TransformPanel.vala:174
-msgid "Transform"
-msgstr "Transformar"
-
-#: Dialogs/ShortcutsDialog.vala:98
-msgid "Raise selection:"
-msgstr "Subir selección:"
-
-#: Dialogs/ShortcutsDialog.vala:100
-msgid "Lower selection:"
-msgstr "Bajar selección:"
-
-#: Dialogs/ShortcutsDialog.vala:102
-msgid "Raise selection to top:"
-msgstr "Traer selección hasta arriba:"
-
-#: Dialogs/ShortcutsDialog.vala:104
-msgid "Lower selection to bottom:"
-msgstr "Enviar selección hasta abajo:"
-
-#: Dialogs/ShortcutsDialog.vala:106
-msgid "Flip horizontally:"
-msgstr "Voltear horizontalmente:"
-
-#: Dialogs/ShortcutsDialog.vala:108
-msgid "Flip vertically:"
-msgstr "Voltear verticalmente:"
-
-#: FileFormat/FileManager.vala:46
-msgid "Save Akira file"
-msgstr "Guardar archivo de Akira"
-
-#: FileFormat/FileManager.vala:48 Layouts/HeaderBar.vala:190
-msgid "Save"
-msgstr "Guardar"
-
-#: FileFormat/FileManager.vala:71
-msgid "Akira files"
-msgstr "Archivos de Akira"
-
-#: FileFormat/FileManager.vala:76
-msgid "All files"
-msgstr "Todos los archivos"
-
-#: FileFormat/FileManager.vala:103
-msgid "Open Akira file"
-msgstr "Abrir archivo de Akira"
-
-#: FileFormat/FileManager.vala:105 Layouts/HeaderBar.vala:170
-msgid "Open"
-msgstr "Abrir"
-
-#: Layouts/HeaderBar.vala:69 Lib/Managers/ExportManager.vala:296
-msgid "Untitled"
-msgstr "Sin título"
-
-#: Layouts/HeaderBar.vala:71
-msgid "Menu"
-msgstr "Menú"
-
-#: Layouts/HeaderBar.vala:75
-msgid "Insert"
-msgstr "Insertar"
-
-#: Layouts/HeaderBar.vala:82
-msgid "Group"
-msgstr "Agrupar"
-
-#: Layouts/HeaderBar.vala:84
-msgid "Ungroup"
-msgstr "Desagrupar"
-
-#: Layouts/HeaderBar.vala:87
-msgid "Up"
-msgstr "Subir"
-
-#: Layouts/HeaderBar.vala:92
-msgid "Down"
-msgstr "Bajar"
-
-#: Layouts/HeaderBar.vala:97
-msgid "Top"
-msgstr "Al principio"
-
-#: Layouts/HeaderBar.vala:102
-msgid "Bottom"
-msgstr "Al final"
-
-#: Layouts/HeaderBar.vala:107
-msgid "Settings"
-msgstr "Configuración"
-
-#: Layouts/HeaderBar.vala:118
-msgid "Difference"
-msgstr "Diferencia"
-
-#: Layouts/HeaderBar.vala:120
-msgid "Exclusion"
-msgstr "Exclusión"
-
-#: Layouts/HeaderBar.vala:122
-msgid "Intersect"
-msgstr "Intersección"
-
-#: Layouts/HeaderBar.vala:124
-msgid "Union"
-msgstr "Unión"
-
-#: Layouts/HeaderBar.vala:161
-msgid "New Window"
-msgstr "Ventana nueva"
-
-#: Layouts/HeaderBar.vala:182
-msgid "Open Recent"
-msgstr "Abrir recientes"
-
-#: Layouts/HeaderBar.vala:195
-msgid "Save As"
-msgstr "Guardar como"
-
-#: Layouts/HeaderBar.vala:204
-msgid "Quit"
-msgstr "Salir"
-
-#: Layouts/HeaderBar.vala:237
-msgid "Artboard"
-msgstr "Mesa de trabajo"
-
-#: Layouts/HeaderBar.vala:254
-msgid "Add Items"
-msgstr "Añadir elementos"
-
-#: Layouts/HeaderBar.vala:262
-msgid "Rectangle"
-msgstr "Rectángulo"
-
-#: Layouts/HeaderBar.vala:268
-msgid "Ellipse"
-msgstr "Elipse"
-
-#: Layouts/HeaderBar.vala:286
-msgid "Vector"
-msgstr "Vector"
-
-#: Layouts/HeaderBar.vala:288
-msgid "Pencil"
-msgstr "Lápiz"
-
-#: Layouts/HeaderBar.vala:291
-msgid "Text"
-msgstr "Texto"
-
-#: Layouts/HeaderBar.vala:297
-msgid "Image"
-msgstr "Imagen"
-
-#: Layouts/HeaderBar.vala:330
-msgid "Export Current Selection"
-msgstr "Exportar selección actual"
-
-#: Layouts/HeaderBar.vala:336
-msgid "Export Artboards"
-msgstr "Exportar mesas de trabajo"
-
-#: Layouts/HeaderBar.vala:345
-msgid "Highlight Area to Export"
-msgstr "Resaltar área que exportar"
-
-#: Layouts/HeaderBar.vala:391
-msgid "Main Menu"
-msgstr "Menú principal"
-
-#: Layouts/HeaderBar.vala:468 Services/ActionManager.vala:218
-#: Services/ActionManager.vala:237 Services/ActionManager.vala:256
-#, c-format
-msgid "Unable to open file at '%s'"
-msgstr "No se puede abrir el archivo en «%s»"
-
-#: Layouts/MainCanvas.vala:52
-msgid "Button was pressed!"
-msgstr "Se ha presionado el botón."
-
-#: Layouts/MainCanvas.vala:160
-msgid "Export completed!"
-msgstr "Finalizó la exportación."
-
-#: Layouts/Partials/AlignItemsPanel.vala:48
-msgid "Distribute Horizontally"
-msgstr "Distribuir horizontalmente"
-
-#: Layouts/Partials/AlignItemsPanel.vala:50
-msgid "Distribute Vertically"
-msgstr "Distribuir verticalmente"
-
-#: Layouts/Partials/AlignItemsPanel.vala:52
-msgid "Align Left"
-msgstr "Alinear a la izquierda"
-
-#: Layouts/Partials/AlignItemsPanel.vala:53
-msgid "Align Center"
-msgstr "Centrar horizontalmente"
-
-#: Layouts/Partials/AlignItemsPanel.vala:54
-msgid "Align Right"
-msgstr "Alinear a la derecha"
-
-#: Layouts/Partials/AlignItemsPanel.vala:56
-msgid "Align Top"
-msgstr "Alinear arriba"
-
-#: Layouts/Partials/AlignItemsPanel.vala:57
-msgid "Align Middle"
-msgstr "Centrar verticalmente"
-
-#: Layouts/Partials/AlignItemsPanel.vala:58
-msgid "Align Bottom"
-msgstr "Alinear abajo"
-
-#: Layouts/Partials/Artboard.vala:144 Layouts/Partials/Artboard.vala:487
-#: Layouts/Partials/Layer.vala:139 Layouts/Partials/Layer.vala:687
-msgid "Lock Layer"
-msgstr "Bloquear capa"
-
-#: Layouts/Partials/Artboard.vala:155 Layouts/Partials/Artboard.vala:529
-#: Layouts/Partials/Layer.vala:156 Layouts/Partials/Layer.vala:729
-msgid "Hide Layer"
-msgstr "Ocultar capa"
-
-#: Layouts/Partials/Artboard.vala:487 Layouts/Partials/Layer.vala:687
-msgid "Unlock Layer"
-msgstr "Desbloquear capa"
-
-#: Layouts/Partials/Artboard.vala:529 Layouts/Partials/Layer.vala:729
-msgid "Show Layer"
-msgstr "Mostrar capa"
-
-#: Layouts/Partials/BorderRadiusPanel.vala:86
-msgid "Style"
-msgstr "Estilo"
-
-#: Layouts/Partials/BorderRadiusPanel.vala:103
-msgid "Border Radius"
-msgstr "Radio de borde"
-
-#: Layouts/Partials/BorderRadiusPanel.vala:198
-msgid "Autoscale Corners"
-msgstr "Escalar esquinas automáticamente"
-
-#: Layouts/Partials/BorderRadiusPanel.vala:207
-msgid "Uniform Corners"
-msgstr "Esquinas uniformes"
-
-#: Layouts/Partials/BordersPanel.vala:53
-msgid "Borders"
-msgstr "Bordes"
-
-#: Layouts/Partials/FillsPanel.vala:54
-msgid "Fills"
-msgstr "Rellenos"
-
-#: Layouts/Partials/TransformPanel.vala:96
-msgid "X"
-msgstr "X"
-
-#: Layouts/Partials/TransformPanel.vala:96
-msgid "Horizontal position"
-msgstr "Posición horizontal"
-
-#: Layouts/Partials/TransformPanel.vala:98
-msgid "Y"
-msgstr "Y"
-
-#: Layouts/Partials/TransformPanel.vala:98
-msgid "Vertical position"
-msgstr "Posición vertical"
-
-#: Layouts/Partials/TransformPanel.vala:100
-msgid "W"
-msgstr "↔"
-
-#: Layouts/Partials/TransformPanel.vala:100
-msgid "Width"
-msgstr "Anchura"
-
-#: Layouts/Partials/TransformPanel.vala:102
-msgid "H"
-msgstr "↕"
-
-#: Layouts/Partials/TransformPanel.vala:102
-msgid "Height"
-msgstr "Altura"
-
-#: Layouts/Partials/TransformPanel.vala:107
-msgid "Lock Ratio"
-msgstr "Bloquear relación"
-
-#: Layouts/Partials/TransformPanel.vala:114
-msgid "R"
-msgstr "↻"
-
-#: Layouts/Partials/TransformPanel.vala:114
-msgid "Rotation degrees"
-msgstr "Grados de giro"
-
-#: Layouts/Partials/TransformPanel.vala:126
-msgid "Flip Horizontally"
-msgstr "Voltear horizontalmente"
-
-#: Layouts/Partials/TransformPanel.vala:137
-msgid "Flip Vertically"
-msgstr "Voltear verticalmente"
-
-#: Layouts/Partials/TransformPanel.vala:165
-msgid "Position"
-msgstr "Posición"
-
-#: Layouts/Partials/TransformPanel.vala:169
-msgid "Size"
-msgstr "Tamaño"
-
-#: Layouts/Partials/TransformPanel.vala:178
-msgid "Opacity"
-msgstr "Opacidad"
-
-#: Layouts/RightSideBar.vala:111
-msgid "Search Layer"
-msgstr "Buscar capa"
-
-#: Lib/Managers/ExportManager.vala:192 Lib/Managers/ExportManager.vala:219
-msgid "Generating preview, please wait…"
-msgstr "Generando previsualización; espere…"
-
-#: Lib/Managers/ExportManager.vala:313
-#, c-format
-msgid "Untitled %i"
-msgstr "Sin título %i"
-
-#: Lib/Managers/ExportManager.vala:484
-msgid "Exporting images…"
-msgstr "Exportando imágenes…"
-
-#: Partials/ExportWidget.vala:117
-#, c-format
-msgid "%i × %i px · %s"
-msgstr "%i × %i px · %s"
-
-#: Partials/ExportWidget.vala:124
-msgid "Fetching image size…"
-msgstr "Recuperando tamaño de imagen…"
-
-#: Partials/ZoomButton.vala:49
-msgid "Zoom Out"
-msgstr "Alejar"
-
-#: Partials/ZoomButton.vala:55
-msgid "Reset Zoom"
-msgstr "Restablecer escala"
-
-#: Partials/ZoomButton.vala:62
-msgid "Zoom In"
-msgstr "Acercar"
-
-#: Partials/ZoomButton.vala:68
-msgid "Zoom"
-msgstr "Escala"
-
-#: Services/ActionManager.vala:211
-msgid "No recently opened file available!"
-msgstr "No hay ningún archivo reciente."
-
-#: Services/ActionManager.vala:230
-msgid "No second most recently opened file available!"
-msgstr "No hay ningún segundo archivo reciente."
-
-#: Services/ActionManager.vala:249
-msgid "No third most recently opened file available!"
-msgstr "No hay ningún tercer archivo reciente."
-
-#: Services/ActionManager.vala:287
-msgid "Nothing selected to export!"
-msgstr "No se ha seleccionado nada para exportar."
-
-#: Services/ActionManager.vala:296
-msgid "Export of Artboards currently unavailable…sorry 😑️"
-msgstr ""
-"La exportación de mesas de trabajo no está disponible por el momento… 😑️"
-
-#: Services/ActionManager.vala:363
-msgid "Choose image file"
-msgstr "Seleccionar archivo de imagen"
-
-#: Services/ActionManager.vala:363
-msgid "Select"
-msgstr "Seleccionar"
-
-#: Services/ActionManager.vala:363
-msgid "Close"
-msgstr "Cerrar"
-
-#: Services/ActionManager.vala:432
-#, c-format
-msgid "Error! .%s files are not supported!"
-msgstr "Error: no se admiten los archivos .%s."
-
-#: Window.vala:119
-msgid "Are you sure you want to quit?"
-msgstr "¿Confirma que quiere salir?"
-
-#: Window.vala:120
-msgid "All unsaved data will be lost and impossible to recover."
-msgstr "Se perderán los datos no guardados y no podrán recuperarse."
-
-#: Window.vala:122
-msgid "Quit without saving!"
-msgstr "Salir sin guardar"
-
-#: Window.vala:123
-msgid "Save file"
-msgstr "Guardar archivo"
diff --git a/po/et.po b/po/et.po
deleted file mode 100644
index ca301d2fd..000000000
--- a/po/et.po
+++ /dev/null
@@ -1,5 +0,0 @@
-msgid ""
-msgstr ""
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
-"Plural-Forms: nplurals=2; plural=n != 1;\n"
diff --git a/po/eu.po b/po/eu.po
deleted file mode 100644
index 7d7bf5d53..000000000
--- a/po/eu.po
+++ /dev/null
@@ -1,4 +0,0 @@
-msgid ""
-msgstr ""
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
diff --git a/po/fa.po b/po/fa.po
deleted file mode 100644
index 7d7bf5d53..000000000
--- a/po/fa.po
+++ /dev/null
@@ -1,4 +0,0 @@
-msgid ""
-msgstr ""
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
diff --git a/po/ff.po b/po/ff.po
deleted file mode 100644
index 7d7bf5d53..000000000
--- a/po/ff.po
+++ /dev/null
@@ -1,4 +0,0 @@
-msgid ""
-msgstr ""
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
diff --git a/po/fi.po b/po/fi.po
deleted file mode 100644
index ca301d2fd..000000000
--- a/po/fi.po
+++ /dev/null
@@ -1,5 +0,0 @@
-msgid ""
-msgstr ""
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
-"Plural-Forms: nplurals=2; plural=n != 1;\n"
diff --git a/po/fj.po b/po/fj.po
deleted file mode 100644
index 7d7bf5d53..000000000
--- a/po/fj.po
+++ /dev/null
@@ -1,4 +0,0 @@
-msgid ""
-msgstr ""
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
diff --git a/po/fo.po b/po/fo.po
deleted file mode 100644
index ca301d2fd..000000000
--- a/po/fo.po
+++ /dev/null
@@ -1,5 +0,0 @@
-msgid ""
-msgstr ""
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
-"Plural-Forms: nplurals=2; plural=n != 1;\n"
diff --git a/po/fr.po b/po/fr.po
deleted file mode 100644
index 7c83c6877..000000000
--- a/po/fr.po
+++ /dev/null
@@ -1,724 +0,0 @@
-msgid ""
-msgstr ""
-"Project-Id-Version: \n"
-"POT-Creation-Date: 2020-10-07 21:17+0200\n"
-"PO-Revision-Date: 2020-10-31 14:08+0100\n"
-"Last-Translator: Yannicka\n"
-"Language-Team: \n"
-"Language: fr\n"
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
-"Content-Transfer-Encoding: 8bit\n"
-"X-Generator: Poedit 2.4.1\n"
-"X-Poedit-Basepath: .\n"
-"Plural-Forms: nplurals=2; plural=(n > 1);\n"
-"X-Poedit-SearchPath-0: .\n"
-
-#: src/Dialogs/ExportDialog.vala:151
-msgid "Export to:"
-msgstr "Exporter vers :"
-
-#: src/Dialogs/ExportDialog.vala:157
-msgid "Select Folder"
-msgstr "Sélectionner un dossier"
-
-#: src/Dialogs/ExportDialog.vala:166
-msgid "Format:"
-msgstr "Format :"
-
-#: src/Dialogs/ExportDialog.vala:179
-msgid "Quality:"
-msgstr "Qualité :"
-
-#: src/Dialogs/ExportDialog.vala:191
-msgid "Compression:"
-msgstr "Compression :"
-
-#: src/Dialogs/ExportDialog.vala:205
-msgid "Transparency:"
-msgstr "Transparence :"
-
-#: src/Dialogs/ExportDialog.vala:218
-msgid "Scale:"
-msgstr "Échelle :"
-
-#: src/Dialogs/ExportDialog.vala:242 src/FileFormat/FileManager.vala:49
-#: src/FileFormat/FileManager.vala:105
-msgid "Cancel"
-msgstr "Annuler"
-
-#: src/Dialogs/ExportDialog.vala:249 src/Dialogs/ShortcutsDialog.vala:63
-#: src/Layouts/HeaderBar.vala:112
-msgid "Export"
-msgstr "Exporter"
-
-#: src/Dialogs/ReleaseDialog.vala:47 src/Dialogs/SettingsDialog.vala:217
-msgid ""
-"WARNING!\n"
-"Akira is still under development and not ready for production. Missing "
-"features, random bugs, and black holes opening in your kitchen are to be "
-"expected."
-msgstr ""
-"ATTENTION !\n"
-"Akira est encore en cours de développement et n'est pas prêt à être "
-"utilisé en production. Attendez-vous à ce que des fonctionnalités "
-"manquent, des bugs se produisent voire qu'un trou noir s'ouvre dans votre "
-"cuisine."
-
-#: src/Dialogs/ReleaseDialog.vala:100 src/Dialogs/SettingsDialog.vala:249
-msgid "Make a Donation"
-msgstr "Faire un don"
-
-#: src/Dialogs/ReleaseDialog.vala:109 src/Dialogs/SettingsDialog.vala:258
-msgid "Suggest Translations"
-msgstr "Suggérer des traductions"
-
-#: src/Dialogs/ReleaseDialog.vala:118 src/Dialogs/SettingsDialog.vala:267
-msgid "Report a Problem"
-msgstr "Signaler un problème"
-
-#: src/Dialogs/SettingsDialog.vala:40
-msgid "Preferences"
-msgstr "Préférences"
-
-#: src/Dialogs/SettingsDialog.vala:50 src/Dialogs/SettingsDialog.vala:73
-#: src/Dialogs/ShortcutsDialog.vala:45
-msgid "General"
-msgstr "Général"
-
-#: src/Dialogs/SettingsDialog.vala:51 src/Dialogs/SettingsDialog.vala:86
-msgid "Interface"
-msgstr "Interface"
-
-#: src/Dialogs/SettingsDialog.vala:52 src/Layouts/HeaderBar.vala:280
-msgid "Shapes"
-msgstr "Formes"
-
-#: src/Dialogs/SettingsDialog.vala:53
-msgid "About"
-msgstr "À propos"
-
-#: src/Dialogs/SettingsDialog.vala:74
-msgid "Auto Reopen Latest File:"
-msgstr "Rouvrir automatiquement le dernier fichier :"
-
-#: src/Dialogs/SettingsDialog.vala:88
-msgid "Use Dark Theme:"
-msgstr "Utiliser le thème sombre :"
-
-#: src/Dialogs/SettingsDialog.vala:92
-msgid "Invert Panels Order:"
-msgstr "Inverser l'ordre des barres latérales :"
-
-#: src/Dialogs/SettingsDialog.vala:96
-msgid "Restart application to apply this change."
-msgstr "Redémarrez l'application pour appliquer ce changement."
-
-#: src/Dialogs/SettingsDialog.vala:100
-msgid "ToolBar Style"
-msgstr "Style de la barre d'outils"
-
-#: src/Dialogs/SettingsDialog.vala:102
-msgid "Show Button Labels:"
-msgstr "Afficher l'étiquette des boutons :"
-
-#: src/Dialogs/SettingsDialog.vala:106
-msgid "Use Symbolic Icons:"
-msgstr "Utiliser les icônes symboliques :"
-
-#: src/Dialogs/SettingsDialog.vala:129
-msgid "Default Colors"
-msgstr "Couleurs par défaut"
-
-#: src/Dialogs/SettingsDialog.vala:131
-msgid "Define the default style used when creating a new shape."
-msgstr ""
-"Définit le style par défaut utilisé lors de la création d'une nouvelle "
-"forme."
-
-#: src/Dialogs/SettingsDialog.vala:136
-msgid "Fill Color:"
-msgstr "Couleur de remplissage :"
-
-#: src/Dialogs/SettingsDialog.vala:157
-msgid "Enable Border Style:"
-msgstr "Activer le style de bordure :"
-
-#: src/Dialogs/SettingsDialog.vala:160
-msgid "Border Color:"
-msgstr "Couleur de la bordure :"
-
-#: src/Dialogs/SettingsDialog.vala:181
-msgid "Border Width:"
-msgstr "Largeur de la bordure :"
-
-#: src/Dialogs/SettingsDialog.vala:209
-msgid "The Linux Design Tool"
-msgstr "L'outil de conception Linux"
-
-#: src/Dialogs/SettingsDialog.vala:226
-msgid "Thanks to our awesome supporters!"
-msgstr "Merci à toutes les merveilleuses personnes qui nous soutiennent !"
-
-#: src/Dialogs/SettingsDialog.vala:231
-msgid "View the list of supporters"
-msgstr "Voir la liste des personnes qui soutiennent le projet"
-
-#: src/Dialogs/ShortcutsDialog.vala:46
-msgid "New window:"
-msgstr "Nouvelle fenêtre :"
-
-#: src/Dialogs/ShortcutsDialog.vala:48
-msgid "Preferences:"
-msgstr "Préférences :"
-
-#: src/Dialogs/ShortcutsDialog.vala:50
-msgid "Quit:"
-msgstr "Quitter :"
-
-#: src/Dialogs/ShortcutsDialog.vala:52
-msgid "Presentation mode:"
-msgstr "Mode présentation :"
-
-#: src/Dialogs/ShortcutsDialog.vala:55
-msgid "File"
-msgstr "Ficher"
-
-#: src/Dialogs/ShortcutsDialog.vala:56
-msgid "Open:"
-msgstr "Ouvrir :"
-
-#: src/Dialogs/ShortcutsDialog.vala:58
-msgid "Save:"
-msgstr "Enregistrer :"
-
-#: src/Dialogs/ShortcutsDialog.vala:60
-msgid "Save as:"
-msgstr "Enregistrer sous :"
-
-#: src/Dialogs/ShortcutsDialog.vala:64
-msgid "Export artboards:"
-msgstr "Exporter les espaces de travail :"
-
-#: src/Dialogs/ShortcutsDialog.vala:66
-msgid "Export selection:"
-msgstr "Exporter la sélection :"
-
-#: src/Dialogs/ShortcutsDialog.vala:68
-msgid "Highlight area to export:"
-msgstr "Sélectionner la zone à exporter :"
-
-#: src/Dialogs/ShortcutsDialog.vala:77
-msgid "Canvas"
-msgstr "Canevas"
-
-#: src/Dialogs/ShortcutsDialog.vala:78
-msgid "Zoom in:"
-msgstr "Zoomer :"
-
-#: src/Dialogs/ShortcutsDialog.vala:80
-msgid "Zoom out:"
-msgstr "Dézoomer :"
-
-#: src/Dialogs/ShortcutsDialog.vala:82
-msgid "Zoom reset:"
-msgstr "Réinitialiser le zoom :"
-
-#: src/Dialogs/ShortcutsDialog.vala:85
-msgid "Item creation"
-msgstr "Création d'élément"
-
-#: src/Dialogs/ShortcutsDialog.vala:86
-msgid "Artboard:"
-msgstr "Espace de travail :"
-
-#: src/Dialogs/ShortcutsDialog.vala:88
-msgid "Rectangle:"
-msgstr "Rectangle :"
-
-#: src/Dialogs/ShortcutsDialog.vala:90
-msgid "Ellipse:"
-msgstr "Ellipse :"
-
-#: src/Dialogs/ShortcutsDialog.vala:92
-msgid "Text:"
-msgstr "Texte :"
-
-#: src/Dialogs/ShortcutsDialog.vala:94
-msgid "Image:"
-msgstr "Image :"
-
-#: src/Dialogs/ShortcutsDialog.vala:97
-#: src/Layouts/Partials/TransformPanel.vala:174
-msgid "Transform"
-msgstr "Transformer"
-
-#: src/Dialogs/ShortcutsDialog.vala:98
-msgid "Raise selection:"
-msgstr "Monter la sélection :"
-
-#: src/Dialogs/ShortcutsDialog.vala:100
-msgid "Lower selection:"
-msgstr "Descendre la sélection :"
-
-#: src/Dialogs/ShortcutsDialog.vala:102
-msgid "Raise selection to top:"
-msgstr "Monter la sélection tout en haut :"
-
-#: src/Dialogs/ShortcutsDialog.vala:104
-msgid "Lower selection to bottom:"
-msgstr "Descendre la sélection tout en bas :"
-
-#: src/Dialogs/ShortcutsDialog.vala:106
-msgid "Flip horizontally:"
-msgstr "Retourner horizontalement :"
-
-#: src/Dialogs/ShortcutsDialog.vala:108
-msgid "Flip vertically:"
-msgstr "Retourner verticalement :"
-
-#: src/FileFormat/FileManager.vala:46
-msgid "Save Akira file"
-msgstr "Enregistrer un fichier Akira"
-
-#: src/FileFormat/FileManager.vala:48 src/Layouts/HeaderBar.vala:190
-msgid "Save"
-msgstr "Enregistrer"
-
-#: src/FileFormat/FileManager.vala:71
-msgid "Akira files"
-msgstr "Fichiers Akira"
-
-#: src/FileFormat/FileManager.vala:76
-msgid "All files"
-msgstr "Tous les fichiers"
-
-#: src/FileFormat/FileManager.vala:103
-msgid "Open Akira file"
-msgstr "Ouvrir un fichier Akira"
-
-#: src/FileFormat/FileManager.vala:105 src/Layouts/HeaderBar.vala:170
-msgid "Open"
-msgstr "Ouvrir"
-
-#: src/Layouts/HeaderBar.vala:69 src/Lib/Managers/ExportManager.vala:296
-msgid "Untitled"
-msgstr "Sans titre"
-
-#: src/Layouts/HeaderBar.vala:71
-msgid "Menu"
-msgstr "Menu"
-
-#: src/Layouts/HeaderBar.vala:75
-msgid "Insert"
-msgstr "Insérer"
-
-#: src/Layouts/HeaderBar.vala:82
-msgid "Group"
-msgstr "Grouper"
-
-#: src/Layouts/HeaderBar.vala:84
-msgid "Ungroup"
-msgstr "Dégrouper"
-
-#: src/Layouts/HeaderBar.vala:87
-msgid "Up"
-msgstr "Monter"
-
-#: src/Layouts/HeaderBar.vala:92
-msgid "Down"
-msgstr "Descendre"
-
-#: src/Layouts/HeaderBar.vala:97
-msgid "Top"
-msgstr "Devant"
-
-#: src/Layouts/HeaderBar.vala:102
-msgid "Bottom"
-msgstr "Derrière"
-
-#: src/Layouts/HeaderBar.vala:107
-msgid "Settings"
-msgstr "Paramètres"
-
-#: src/Layouts/HeaderBar.vala:118
-msgid "Difference"
-msgstr "Différence"
-
-#: src/Layouts/HeaderBar.vala:120
-msgid "Exclusion"
-msgstr "Exclusion"
-
-#: src/Layouts/HeaderBar.vala:122
-msgid "Intersect"
-msgstr "Intersection"
-
-#: src/Layouts/HeaderBar.vala:124
-msgid "Union"
-msgstr "Union"
-
-#: src/Layouts/HeaderBar.vala:161
-msgid "New Window"
-msgstr "Nouvelle fenêtre"
-
-#: src/Layouts/HeaderBar.vala:182
-msgid "Open Recent"
-msgstr "Ouvert récemment"
-
-#: src/Layouts/HeaderBar.vala:195
-msgid "Save As"
-msgstr "Enregistrer sous..."
-
-#: src/Layouts/HeaderBar.vala:204
-msgid "Quit"
-msgstr "Quitter"
-
-#: src/Layouts/HeaderBar.vala:237
-msgid "Artboard"
-msgstr "Espace de travail"
-
-#: src/Layouts/HeaderBar.vala:254
-msgid "Add Items"
-msgstr "Ajouter des éléments"
-
-#: src/Layouts/HeaderBar.vala:262
-msgid "Rectangle"
-msgstr "Rectangle"
-
-#: src/Layouts/HeaderBar.vala:268
-msgid "Ellipse"
-msgstr "Ellipse"
-
-#: src/Layouts/HeaderBar.vala:286
-msgid "Vector"
-msgstr "Vecteur"
-
-#: src/Layouts/HeaderBar.vala:288
-msgid "Pencil"
-msgstr "Crayon"
-
-#: src/Layouts/HeaderBar.vala:291
-msgid "Text"
-msgstr "Texte"
-
-#: src/Layouts/HeaderBar.vala:297
-msgid "Image"
-msgstr "Image"
-
-#: src/Layouts/HeaderBar.vala:330
-msgid "Export Current Selection"
-msgstr "Exporter la sélection courante"
-
-#: src/Layouts/HeaderBar.vala:336
-msgid "Export Artboards"
-msgstr "Exporter les espaces de travail"
-
-#: src/Layouts/HeaderBar.vala:345
-msgid "Highlight Area to Export"
-msgstr "Sélectionner la zone à exporter"
-
-#: src/Layouts/HeaderBar.vala:391
-msgid "Main Menu"
-msgstr "Menu principal"
-
-#: src/Layouts/HeaderBar.vala:468 src/Services/ActionManager.vala:224
-#: src/Services/ActionManager.vala:243 src/Services/ActionManager.vala:262
-#, c-format
-msgid "Unable to open file at '%s'"
-msgstr "Impossible d'ouvrir le fichier « %s »"
-
-#: src/Layouts/MainCanvas.vala:46
-msgid "Button was pressed!"
-msgstr "Un bouton a été pressé !"
-
-#: src/Layouts/MainCanvas.vala:206
-msgid "Export completed!"
-msgstr "Export terminée !"
-
-#: src/Layouts/Partials/AlignItemsPanel.vala:48
-msgid "Distribute Horizontally"
-msgstr "Distribuer horizontalement"
-
-#: src/Layouts/Partials/AlignItemsPanel.vala:50
-msgid "Distribute Vertically"
-msgstr "Distribuer verticalement"
-
-#: src/Layouts/Partials/AlignItemsPanel.vala:52
-msgid "Align Left"
-msgstr "Aligner à gauche"
-
-#: src/Layouts/Partials/AlignItemsPanel.vala:53
-msgid "Align Center"
-msgstr "Aligner au centre"
-
-#: src/Layouts/Partials/AlignItemsPanel.vala:54
-msgid "Align Right"
-msgstr "Aligner à droite"
-
-#: src/Layouts/Partials/AlignItemsPanel.vala:56
-msgid "Align Top"
-msgstr "Aligner en haut"
-
-#: src/Layouts/Partials/AlignItemsPanel.vala:57
-msgid "Align Middle"
-msgstr "Aligner au milieu"
-
-#: src/Layouts/Partials/AlignItemsPanel.vala:58
-msgid "Align Bottom"
-msgstr "Aligner en bas"
-
-#: src/Layouts/Partials/Artboard.vala:144
-#: src/Layouts/Partials/Artboard.vala:487 src/Layouts/Partials/Layer.vala:139
-#: src/Layouts/Partials/Layer.vala:687
-msgid "Lock Layer"
-msgstr "Verrouiller le calque"
-
-#: src/Layouts/Partials/Artboard.vala:155
-#: src/Layouts/Partials/Artboard.vala:529 src/Layouts/Partials/Layer.vala:156
-#: src/Layouts/Partials/Layer.vala:729
-msgid "Hide Layer"
-msgstr "Cacher le calque"
-
-#: src/Layouts/Partials/Artboard.vala:487 src/Layouts/Partials/Layer.vala:687
-msgid "Unlock Layer"
-msgstr "Dévérouiller le calque"
-
-#: src/Layouts/Partials/Artboard.vala:529 src/Layouts/Partials/Layer.vala:729
-msgid "Show Layer"
-msgstr "Afficher le calque"
-
-#: src/Layouts/Partials/BorderItem.vala:121
-msgid "Choose border color"
-msgstr "Choisir la couleur de la bordure"
-
-#: src/Layouts/Partials/BorderItem.vala:176
-#: src/Layouts/Partials/FillItem.vala:178
-msgid "Pick color"
-msgstr "Choisir une couleur"
-
-#: src/Layouts/Partials/BorderItem.vala:191
-msgid "Remove border"
-msgstr "Supprimer la bordure"
-
-#: src/Layouts/Partials/BorderItem.vala:275
-msgid "Show border"
-msgstr "Afficher la bordure"
-
-#: src/Layouts/Partials/BorderItem.vala:279
-msgid "Hide border"
-msgstr "Masquer la bordure"
-
-#: src/Layouts/Partials/BorderRadiusPanel.vala:86
-msgid "Style"
-msgstr "Style"
-
-#: src/Layouts/Partials/BorderRadiusPanel.vala:103
-msgid "Border Radius"
-msgstr "Arrondi"
-
-#: src/Layouts/Partials/BorderRadiusPanel.vala:137
-msgid "Border radius options"
-msgstr "Options de l'arrondi"
-
-#: src/Layouts/Partials/BorderRadiusPanel.vala:199
-msgid "Autoscale Corners"
-msgstr "Mise à l'échelle automatique des coins"
-
-#: src/Layouts/Partials/BorderRadiusPanel.vala:208
-msgid "Uniform Corners"
-msgstr "Coins uniformes"
-
-#: src/Layouts/Partials/BordersPanel.vala:53
-msgid "Borders"
-msgstr "Bordures"
-
-#: src/Layouts/Partials/BordersPanel.vala:64
-msgid "Add border"
-msgstr "Ajouter une bordure"
-
-#: src/Layouts/Partials/FillItem.vala:114
-msgid "Choose fill color"
-msgstr "Choisir la couleur de remplissage"
-
-#: src/Layouts/Partials/FillItem.vala:193
-msgid "Remove fill color"
-msgstr "Supprimer la couleur de remplissage"
-
-#: src/Layouts/Partials/FillItem.vala:277
-msgid "Show fill color"
-msgstr "Afficher la couleur de remplissage"
-
-#: src/Layouts/Partials/FillItem.vala:281
-msgid "Hide fill color"
-msgstr "Masquer la couleur de remplissage"
-
-#: src/Layouts/Partials/FillsPanel.vala:54
-msgid "Fills"
-msgstr "Remplissages"
-
-#: src/Layouts/Partials/FillsPanel.vala:65
-msgid "Add fill color"
-msgstr "Ajouter une couleur de remplissage"
-
-#: src/Layouts/Partials/TransformPanel.vala:96
-msgid "X"
-msgstr "X"
-
-#: src/Layouts/Partials/TransformPanel.vala:96
-msgid "Horizontal position"
-msgstr "Position horizontale"
-
-#: src/Layouts/Partials/TransformPanel.vala:98
-msgid "Y"
-msgstr "Y"
-
-#: src/Layouts/Partials/TransformPanel.vala:98
-msgid "Vertical position"
-msgstr "Position verticale"
-
-#: src/Layouts/Partials/TransformPanel.vala:100
-msgid "W"
-msgstr "L"
-
-#: src/Layouts/Partials/TransformPanel.vala:100
-msgid "Width"
-msgstr "Largeur"
-
-#: src/Layouts/Partials/TransformPanel.vala:102
-msgid "H"
-msgstr "H"
-
-#: src/Layouts/Partials/TransformPanel.vala:102
-msgid "Height"
-msgstr "Hauteur"
-
-#: src/Layouts/Partials/TransformPanel.vala:107
-msgid "Lock Ratio"
-msgstr "Verrouiller le ratio"
-
-#: src/Layouts/Partials/TransformPanel.vala:114
-msgid "R"
-msgstr "A"
-
-#: src/Layouts/Partials/TransformPanel.vala:114
-msgid "Rotation degrees"
-msgstr "Angle de rotation"
-
-#: src/Layouts/Partials/TransformPanel.vala:126
-msgid "Flip Horizontally"
-msgstr "Retourner horizontalement"
-
-#: src/Layouts/Partials/TransformPanel.vala:137
-msgid "Flip Vertically"
-msgstr "Retourner verticalement"
-
-#: src/Layouts/Partials/TransformPanel.vala:165
-msgid "Position"
-msgstr "Position"
-
-#: src/Layouts/Partials/TransformPanel.vala:169
-msgid "Size"
-msgstr "Taille"
-
-#: src/Layouts/Partials/TransformPanel.vala:178
-msgid "Opacity"
-msgstr "Opacité"
-
-#: src/Layouts/RightSideBar.vala:111
-msgid "Search Layer"
-msgstr "Rechercher un calque"
-
-#: src/Lib/Managers/ExportManager.vala:192
-#: src/Lib/Managers/ExportManager.vala:219
-msgid "Generating preview, please wait…"
-msgstr "Génération de l'aperçu, veuillez patienter…"
-
-#: src/Lib/Managers/ExportManager.vala:313
-#, c-format
-msgid "Untitled %i"
-msgstr "Sans titre %i"
-
-#: src/Lib/Managers/ExportManager.vala:484
-msgid "Exporting images…"
-msgstr "Export des images en cours…"
-
-#: src/Partials/ExportWidget.vala:117
-#, c-format
-msgid "%i × %i px · %s"
-msgstr "%i × %i px · %s"
-
-#: src/Partials/ExportWidget.vala:124
-msgid "Fetching image size…"
-msgstr "Récupération de la taille de l'image…"
-
-#: src/Partials/ZoomButton.vala:49
-msgid "Zoom Out"
-msgstr "Dézoomer"
-
-#: src/Partials/ZoomButton.vala:55
-msgid "Reset Zoom"
-msgstr "Réinitialiser le zoom"
-
-#: src/Partials/ZoomButton.vala:62
-msgid "Zoom In"
-msgstr "Zoomer"
-
-#: src/Partials/ZoomButton.vala:68
-msgid "Zoom"
-msgstr "Zoom"
-
-#: src/Services/ActionManager.vala:217
-msgid "No recently opened file available!"
-msgstr "Aucun dossier récemment ouvert n'est disponible !"
-
-#: src/Services/ActionManager.vala:236
-msgid "No second most recently opened file available!"
-msgstr "Pas de deuxième fichier le plus récemment ouvert disponible !"
-
-#: src/Services/ActionManager.vala:255
-msgid "No third most recently opened file available!"
-msgstr "Pas de troisième fichier le plus récemment ouvert disponible !"
-
-#: src/Services/ActionManager.vala:293
-msgid "Nothing selected to export!"
-msgstr "Aucun élément sélectionné pour l'export !"
-
-#: src/Services/ActionManager.vala:302
-msgid "Export of Artboards currently unavailable…sorry 😑️"
-msgstr ""
-"L'export des espaces de travail est actuellement indisponible… pardon 😑️"
-
-#: src/Services/ActionManager.vala:373
-msgid "Choose image file"
-msgstr "Choisir un fichier image"
-
-#: src/Services/ActionManager.vala:373
-msgid "Select"
-msgstr "Sélectionner"
-
-#: src/Services/ActionManager.vala:373
-msgid "Close"
-msgstr "Fermer"
-
-#: src/Services/ActionManager.vala:442
-#, c-format
-msgid "Error! .%s files are not supported!"
-msgstr "Erreur ! Les fichiers .%s ne sont pas pris en charge !"
-
-#: src/Window.vala:121
-msgid "Are you sure you want to quit?"
-msgstr "Êtes-vous sûr de vouloir quitter ?"
-
-#: src/Window.vala:122
-msgid "All unsaved data will be lost and impossible to recover."
-msgstr ""
-"Toutes les données non sauvegardées seront perdues et impossibles à "
-"récupérer."
-
-#: src/Window.vala:124
-msgid "Quit without saving!"
-msgstr "Quitter sans sauvegarder !"
-
-#: src/Window.vala:125
-msgid "Save file"
-msgstr "Enregistrer le fichier"
diff --git a/po/fr_CA.po b/po/fr_CA.po
deleted file mode 100644
index 044613fb7..000000000
--- a/po/fr_CA.po
+++ /dev/null
@@ -1,5 +0,0 @@
-msgid ""
-msgstr ""
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
-"Plural-Forms: nplurals=2; plural=n>1;\n"
diff --git a/po/fy.po b/po/fy.po
deleted file mode 100644
index 7d7bf5d53..000000000
--- a/po/fy.po
+++ /dev/null
@@ -1,4 +0,0 @@
-msgid ""
-msgstr ""
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
diff --git a/po/ga.po b/po/ga.po
deleted file mode 100644
index 7d7bf5d53..000000000
--- a/po/ga.po
+++ /dev/null
@@ -1,4 +0,0 @@
-msgid ""
-msgstr ""
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
diff --git a/po/gd.po b/po/gd.po
deleted file mode 100644
index 7d7bf5d53..000000000
--- a/po/gd.po
+++ /dev/null
@@ -1,4 +0,0 @@
-msgid ""
-msgstr ""
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
diff --git a/po/gl.po b/po/gl.po
deleted file mode 100644
index 7d7bf5d53..000000000
--- a/po/gl.po
+++ /dev/null
@@ -1,4 +0,0 @@
-msgid ""
-msgstr ""
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
diff --git a/po/gn.po b/po/gn.po
deleted file mode 100644
index 7d7bf5d53..000000000
--- a/po/gn.po
+++ /dev/null
@@ -1,4 +0,0 @@
-msgid ""
-msgstr ""
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
diff --git a/po/gu.po b/po/gu.po
deleted file mode 100644
index 7d7bf5d53..000000000
--- a/po/gu.po
+++ /dev/null
@@ -1,4 +0,0 @@
-msgid ""
-msgstr ""
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
diff --git a/po/gv.po b/po/gv.po
deleted file mode 100644
index 7d7bf5d53..000000000
--- a/po/gv.po
+++ /dev/null
@@ -1,4 +0,0 @@
-msgid ""
-msgstr ""
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
diff --git a/po/ha.po b/po/ha.po
deleted file mode 100644
index 7d7bf5d53..000000000
--- a/po/ha.po
+++ /dev/null
@@ -1,4 +0,0 @@
-msgid ""
-msgstr ""
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
diff --git a/po/he.po b/po/he.po
deleted file mode 100644
index ca301d2fd..000000000
--- a/po/he.po
+++ /dev/null
@@ -1,5 +0,0 @@
-msgid ""
-msgstr ""
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
-"Plural-Forms: nplurals=2; plural=n != 1;\n"
diff --git a/po/hi.po b/po/hi.po
deleted file mode 100644
index 7d7bf5d53..000000000
--- a/po/hi.po
+++ /dev/null
@@ -1,4 +0,0 @@
-msgid ""
-msgstr ""
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
diff --git a/po/ho.po b/po/ho.po
deleted file mode 100644
index 7d7bf5d53..000000000
--- a/po/ho.po
+++ /dev/null
@@ -1,4 +0,0 @@
-msgid ""
-msgstr ""
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
diff --git a/po/hr.po b/po/hr.po
deleted file mode 100644
index 6188ef853..000000000
--- a/po/hr.po
+++ /dev/null
@@ -1,5 +0,0 @@
-msgid ""
-msgstr ""
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
-"Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n"
diff --git a/po/ht.po b/po/ht.po
deleted file mode 100644
index 7d7bf5d53..000000000
--- a/po/ht.po
+++ /dev/null
@@ -1,4 +0,0 @@
-msgid ""
-msgstr ""
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
diff --git a/po/hu.po b/po/hu.po
deleted file mode 100644
index ca301d2fd..000000000
--- a/po/hu.po
+++ /dev/null
@@ -1,5 +0,0 @@
-msgid ""
-msgstr ""
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
-"Plural-Forms: nplurals=2; plural=n != 1;\n"
diff --git a/po/hy.po b/po/hy.po
deleted file mode 100644
index 7d7bf5d53..000000000
--- a/po/hy.po
+++ /dev/null
@@ -1,4 +0,0 @@
-msgid ""
-msgstr ""
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
diff --git a/po/hz.po b/po/hz.po
deleted file mode 100644
index 7d7bf5d53..000000000
--- a/po/hz.po
+++ /dev/null
@@ -1,4 +0,0 @@
-msgid ""
-msgstr ""
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
diff --git a/po/ia.po b/po/ia.po
deleted file mode 100644
index 7d7bf5d53..000000000
--- a/po/ia.po
+++ /dev/null
@@ -1,4 +0,0 @@
-msgid ""
-msgstr ""
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
diff --git a/po/id.po b/po/id.po
deleted file mode 100644
index 7d7bf5d53..000000000
--- a/po/id.po
+++ /dev/null
@@ -1,4 +0,0 @@
-msgid ""
-msgstr ""
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
diff --git a/po/ie.po b/po/ie.po
deleted file mode 100644
index 7d7bf5d53..000000000
--- a/po/ie.po
+++ /dev/null
@@ -1,4 +0,0 @@
-msgid ""
-msgstr ""
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
diff --git a/po/ig.po b/po/ig.po
deleted file mode 100644
index 7d7bf5d53..000000000
--- a/po/ig.po
+++ /dev/null
@@ -1,4 +0,0 @@
-msgid ""
-msgstr ""
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
diff --git a/po/ii.po b/po/ii.po
deleted file mode 100644
index 7d7bf5d53..000000000
--- a/po/ii.po
+++ /dev/null
@@ -1,4 +0,0 @@
-msgid ""
-msgstr ""
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
diff --git a/po/ik.po b/po/ik.po
deleted file mode 100644
index 7d7bf5d53..000000000
--- a/po/ik.po
+++ /dev/null
@@ -1,4 +0,0 @@
-msgid ""
-msgstr ""
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
diff --git a/po/io.po b/po/io.po
deleted file mode 100644
index 7d7bf5d53..000000000
--- a/po/io.po
+++ /dev/null
@@ -1,4 +0,0 @@
-msgid ""
-msgstr ""
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
diff --git a/po/is.po b/po/is.po
deleted file mode 100644
index 7d7bf5d53..000000000
--- a/po/is.po
+++ /dev/null
@@ -1,4 +0,0 @@
-msgid ""
-msgstr ""
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
diff --git a/po/it.po b/po/it.po
deleted file mode 100644
index 336429033..000000000
--- a/po/it.po
+++ /dev/null
@@ -1,671 +0,0 @@
-#
-# XP312 < >, 2020.
-# Saverio , 2021.
-#
-msgid ""
-msgstr ""
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
-"Plural-Forms: nplurals=2; plural=(n != 1)\n"
-"Project-Id-Version: unnamed project\n"
-"Last-Translator: Saverio \n"
-"Language-Team: Italian \n"
-"Language: it\n"
-"Content-Transfer-Encoding: 8bit\n"
-"PO-Revision-Date: 2021-06-28 18:59+0200\n"
-"X-Generator: Gtranslator 40.0\n"
-
-#: Dialogs/ExportDialog.vala:151
-msgid "Export to:"
-msgstr "Esporta come:"
-
-#: Dialogs/ExportDialog.vala:157
-msgid "Select Folder"
-msgstr "Seleziona la cartella"
-
-#: Dialogs/ExportDialog.vala:166
-msgid "Format:"
-msgstr "Formato:"
-
-#: Dialogs/ExportDialog.vala:180
-msgid "Quality:"
-msgstr "Qualità:"
-
-#: Dialogs/ExportDialog.vala:192
-msgid "Compression:"
-msgstr "Compressione:"
-
-#: Dialogs/ExportDialog.vala:206
-msgid "Transparency:"
-msgstr "Trasparenza:"
-
-#: Dialogs/ExportDialog.vala:219
-msgid "Scale:"
-msgstr "Scala:"
-
-#: Dialogs/ExportDialog.vala:243 FileFormat/FileManager.vala:49
-#: FileFormat/FileManager.vala:105
-msgid "Cancel"
-msgstr "Annulla"
-
-#: Dialogs/ExportDialog.vala:250 Dialogs/ShortcutsDialog.vala:63
-#: Layouts/HeaderBar.vala:112
-msgid "Export"
-msgstr "Esporta"
-
-#: Dialogs/ReleaseDialog.vala:47 Dialogs/SettingsDialog.vala:217
-msgid ""
-"WARNING!\n"
-"Akira is still under development and not ready for production. Missing "
-"features, random bugs, and black holes opening in your kitchen are to be "
-"expected."
-msgstr ""
-"ATTENZIONE!\n"
-"Akira è ancora in fase di sviluppo e non è pronta per la produzione. "
-"Potrebbero verificarsi bug casuali, funzionalità mancanti, o apertura di "
-"buchi neri nella tua cucina."
-
-#: Dialogs/ReleaseDialog.vala:100 Dialogs/SettingsDialog.vala:249
-msgid "Make a Donation"
-msgstr "Fai una donazione"
-
-#: Dialogs/ReleaseDialog.vala:109 Dialogs/SettingsDialog.vala:258
-msgid "Suggest Translations"
-msgstr "Suggerisci traduzione"
-
-#: Dialogs/ReleaseDialog.vala:118 Dialogs/SettingsDialog.vala:267
-msgid "Report a Problem"
-msgstr "Segnala un problema"
-
-#: Dialogs/SettingsDialog.vala:40
-msgid "Preferences"
-msgstr "Preferenze"
-
-#: Dialogs/SettingsDialog.vala:50 Dialogs/SettingsDialog.vala:73
-#: Dialogs/ShortcutsDialog.vala:45
-msgid "General"
-msgstr "Generale"
-
-#: Dialogs/SettingsDialog.vala:51 Dialogs/SettingsDialog.vala:86
-msgid "Interface"
-msgstr "Interfaccia"
-
-#: Dialogs/SettingsDialog.vala:52 Layouts/HeaderBar.vala:280
-msgid "Shapes"
-msgstr "Figure"
-
-#: Dialogs/SettingsDialog.vala:53
-msgid "About"
-msgstr "Informazioni"
-
-# In Italian the literal translation would be a little weird, so I've added a "edited" at the end of the sentence
-#: Dialogs/SettingsDialog.vala:74
-msgid "Auto Reopen Latest File:"
-msgstr "Apri automaticamente l'ultimo file modificato"
-
-#: Dialogs/SettingsDialog.vala:88
-msgid "Use Dark Theme:"
-msgstr "Utilizza il tema scuro:"
-
-#: Dialogs/SettingsDialog.vala:92
-msgid "Invert Panels Order:"
-msgstr "Inverti l'ordine dei pannelli:"
-
-#: Dialogs/SettingsDialog.vala:96
-msgid "Restart application to apply this change."
-msgstr "Riavvia l'applicazione applicare questa modifica"
-
-#: Dialogs/SettingsDialog.vala:100
-msgid "ToolBar Style"
-msgstr "Stile della barra degli strumenti"
-
-#: Dialogs/SettingsDialog.vala:102
-msgid "Show Button Labels:"
-msgstr "Mostra le etichette dei pulsanti:"
-
-#: Dialogs/SettingsDialog.vala:106
-msgid "Use Symbolic Icons:"
-msgstr "Utilizza le icone simboliche:"
-
-#: Dialogs/SettingsDialog.vala:129
-msgid "Default Colors"
-msgstr "Colori predefiniti"
-
-#: Dialogs/SettingsDialog.vala:131
-msgid "Define the default style used when creating a new shape."
-msgstr ""
-"Definisci lo stile predefinito usato quando viene creata una nuova figura."
-
-#: Dialogs/SettingsDialog.vala:136
-msgid "Fill Color:"
-msgstr "Colore di riempimento:"
-
-#: Dialogs/SettingsDialog.vala:157
-msgid "Enable Border Style:"
-msgstr "Attiva lo stile dei bordi:"
-
-#: Dialogs/SettingsDialog.vala:160
-msgid "Border Color:"
-msgstr "Colore dei bordi:"
-
-#: Dialogs/SettingsDialog.vala:181
-msgid "Border Width:"
-msgstr "Spessore dei bordi:"
-
-#: Dialogs/SettingsDialog.vala:209
-msgid "The Linux Design Tool"
-msgstr "Lo strumento di design di Linux"
-
-#: Dialogs/SettingsDialog.vala:226
-msgid "Thanks to our awesome supporters!"
-msgstr "Grazie ai nostri meravigliosi collaboratori!"
-
-#: Dialogs/SettingsDialog.vala:231
-msgid "View the list of supporters"
-msgstr "Visualizza la lista dei collaboratori"
-
-#: Dialogs/ShortcutsDialog.vala:46
-msgid "New window:"
-msgstr "Nuova finestra:"
-
-#: Dialogs/ShortcutsDialog.vala:48
-msgid "Preferences:"
-msgstr "Preferenze:"
-
-#: Dialogs/ShortcutsDialog.vala:50
-msgid "Quit:"
-msgstr "Esci:"
-
-#: Dialogs/ShortcutsDialog.vala:52
-msgid "Presentation mode:"
-msgstr "Modalità presentazione:"
-
-#: Dialogs/ShortcutsDialog.vala:55
-msgid "File"
-msgstr "File"
-
-#: Dialogs/ShortcutsDialog.vala:56
-msgid "Open:"
-msgstr "Apri:"
-
-#: Dialogs/ShortcutsDialog.vala:58
-msgid "Save:"
-msgstr "Salva:"
-
-#: Dialogs/ShortcutsDialog.vala:60
-msgid "Save as:"
-msgstr "Salva come:"
-
-#: Dialogs/ShortcutsDialog.vala:64
-msgid "Export artboards:"
-msgstr "Esporta artboard:"
-
-#: Dialogs/ShortcutsDialog.vala:66
-msgid "Export selection:"
-msgstr "Esporta la selezione:"
-
-#: Dialogs/ShortcutsDialog.vala:68
-msgid "Highlight area to export:"
-msgstr "Evidenzia l'area da esportare:"
-
-#: Dialogs/ShortcutsDialog.vala:77
-msgid "Canvas"
-msgstr "Canvas"
-
-#: Dialogs/ShortcutsDialog.vala:78
-msgid "Zoom in:"
-msgstr "Aumenta lo zoom:"
-
-#: Dialogs/ShortcutsDialog.vala:80
-msgid "Zoom out:"
-msgstr "Riduci lo zoom:"
-
-#: Dialogs/ShortcutsDialog.vala:82
-msgid "Zoom reset:"
-msgstr "Reimposta lo zoom:"
-
-#: Dialogs/ShortcutsDialog.vala:85
-msgid "Item creation"
-msgstr "Creazione elemento"
-
-#: Dialogs/ShortcutsDialog.vala:86
-msgid "Artboard:"
-msgstr "Artboard:"
-
-#: Dialogs/ShortcutsDialog.vala:88
-msgid "Rectangle:"
-msgstr "Rettangolo:"
-
-#: Dialogs/ShortcutsDialog.vala:90
-msgid "Ellipse:"
-msgstr "Ellisse:"
-
-#: Dialogs/ShortcutsDialog.vala:92
-msgid "Text:"
-msgstr "Testo:"
-
-#: Dialogs/ShortcutsDialog.vala:94
-msgid "Image:"
-msgstr "Immagine:"
-
-#: Dialogs/ShortcutsDialog.vala:97 Layouts/Partials/TransformPanel.vala:174
-msgid "Transform"
-msgstr "Trasforma:"
-
-#: Dialogs/ShortcutsDialog.vala:98
-msgid "Raise selection:"
-msgstr "Porta la selezione sopra:"
-
-#: Dialogs/ShortcutsDialog.vala:100
-msgid "Lower selection:"
-msgstr "Porta la selezione in basso:"
-
-#: Dialogs/ShortcutsDialog.vala:102
-msgid "Raise selection to top:"
-msgstr "Porta la selezione in primo piano:"
-
-#: Dialogs/ShortcutsDialog.vala:104
-msgid "Lower selection to bottom:"
-msgstr "Porta la selezione in ultimo piano:"
-
-#: Dialogs/ShortcutsDialog.vala:106
-msgid "Flip horizontally:"
-msgstr "Capovolgi orizzontalmente:"
-
-#: Dialogs/ShortcutsDialog.vala:108
-msgid "Flip vertically:"
-msgstr "Capovolgi verticalmente:"
-
-#: FileFormat/FileManager.vala:46
-msgid "Save Akira file"
-msgstr "Salva file Akira"
-
-#: FileFormat/FileManager.vala:48 Layouts/HeaderBar.vala:190
-msgid "Save"
-msgstr "Salva"
-
-#: FileFormat/FileManager.vala:71
-msgid "Akira files"
-msgstr "File Akira"
-
-#: FileFormat/FileManager.vala:76
-msgid "All files"
-msgstr "Tutti i file"
-
-#: FileFormat/FileManager.vala:103
-msgid "Open Akira file"
-msgstr "Apri file Akira"
-
-#: FileFormat/FileManager.vala:105 Layouts/HeaderBar.vala:170
-msgid "Open"
-msgstr "Apri"
-
-#: Layouts/HeaderBar.vala:69 Lib/Managers/ExportManager.vala:296
-msgid "Untitled"
-msgstr "Senza titolo"
-
-#: Layouts/HeaderBar.vala:71
-msgid "Menu"
-msgstr "Menu"
-
-#: Layouts/HeaderBar.vala:75
-msgid "Insert"
-msgstr "Inserisci"
-
-#: Layouts/HeaderBar.vala:82
-msgid "Group"
-msgstr "Ragruppa"
-
-#: Layouts/HeaderBar.vala:84
-msgid "Ungroup"
-msgstr "Separa"
-
-#: Layouts/HeaderBar.vala:87
-msgid "Up"
-msgstr "Sopra"
-
-#: Layouts/HeaderBar.vala:92
-msgid "Down"
-msgstr "Sotto"
-
-#: Layouts/HeaderBar.vala:97
-msgid "Top"
-msgstr "Più in alto"
-
-#: Layouts/HeaderBar.vala:102
-msgid "Bottom"
-msgstr "Più in basso"
-
-#: Layouts/HeaderBar.vala:107
-msgid "Settings"
-msgstr "Impostazioni"
-
-# ?
-#: Layouts/HeaderBar.vala:118
-msgid "Difference"
-msgstr "Differenza"
-
-#: Layouts/HeaderBar.vala:120
-msgid "Exclusion"
-msgstr "Esclusione"
-
-#: Layouts/HeaderBar.vala:122
-msgid "Intersect"
-msgstr "Intersezione"
-
-#: Layouts/HeaderBar.vala:124
-msgid "Union"
-msgstr "Unione"
-
-#: Layouts/HeaderBar.vala:161
-msgid "New Window"
-msgstr "Nuova finestra"
-
-#: Layouts/HeaderBar.vala:182
-msgid "Open Recent"
-msgstr "Apri recenti"
-
-#: Layouts/HeaderBar.vala:195
-msgid "Save As"
-msgstr "Salva come"
-
-#: Layouts/HeaderBar.vala:204
-msgid "Quit"
-msgstr "Esci"
-
-#: Layouts/HeaderBar.vala:237
-msgid "Artboard"
-msgstr "Artboard"
-
-#: Layouts/HeaderBar.vala:254
-msgid "Add Items"
-msgstr "Aggiungi elementi"
-
-#: Layouts/HeaderBar.vala:262
-msgid "Rectangle"
-msgstr "Rettangolo"
-
-#: Layouts/HeaderBar.vala:268
-msgid "Ellipse"
-msgstr "Ellisse"
-
-#: Layouts/HeaderBar.vala:286
-msgid "Vector"
-msgstr "Vettore"
-
-#: Layouts/HeaderBar.vala:288
-msgid "Pencil"
-msgstr "Matita"
-
-#: Layouts/HeaderBar.vala:291
-msgid "Text"
-msgstr "Testo"
-
-#: Layouts/HeaderBar.vala:297
-msgid "Image"
-msgstr "Immagine"
-
-#: Layouts/HeaderBar.vala:330
-msgid "Export Current Selection"
-msgstr "Esporta selezione corrente"
-
-#: Layouts/HeaderBar.vala:336
-msgid "Export Artboards"
-msgstr "Esporta le artboard"
-
-#: Layouts/HeaderBar.vala:345
-msgid "Highlight Area to Export"
-msgstr "Evidenza l'area da esportare"
-
-#: Layouts/HeaderBar.vala:391
-msgid "Main Menu"
-msgstr "Menu principale"
-
-#: Layouts/HeaderBar.vala:468 Services/ActionManager.vala:218
-#: Services/ActionManager.vala:237 Services/ActionManager.vala:256
-#, c-format
-msgid "Unable to open file at '%s'"
-msgstr "Non è possibile aprirle il file “%s”"
-
-#: Layouts/MainCanvas.vala:52
-msgid "Button was pressed!"
-msgstr "Il pulsante è stato premuto!"
-
-#: Layouts/MainCanvas.vala:160
-msgid "Export completed!"
-msgstr "Esportazione completata!"
-
-#: Layouts/Partials/AlignItemsPanel.vala:48
-msgid "Distribute Horizontally"
-msgstr "Distribuisci orizzontalmente"
-
-#: Layouts/Partials/AlignItemsPanel.vala:50
-msgid "Distribute Vertically"
-msgstr "Distribuisci verticalmente"
-
-#: Layouts/Partials/AlignItemsPanel.vala:52
-msgid "Align Left"
-msgstr "Allineamento a sinistra"
-
-#: Layouts/Partials/AlignItemsPanel.vala:53
-msgid "Align Center"
-msgstr "Allineamento al centro"
-
-#: Layouts/Partials/AlignItemsPanel.vala:54
-msgid "Align Right"
-msgstr "Allicenamento a destra"
-
-#: Layouts/Partials/AlignItemsPanel.vala:56
-msgid "Align Top"
-msgstr "Allineamento in alto"
-
-#: Layouts/Partials/AlignItemsPanel.vala:57
-msgid "Align Middle"
-msgstr "Allineamento al centro"
-
-#: Layouts/Partials/AlignItemsPanel.vala:58
-msgid "Align Bottom"
-msgstr "Allineamento in basso"
-
-#: Layouts/Partials/Artboard.vala:144 Layouts/Partials/Artboard.vala:487
-#: Layouts/Partials/Layer.vala:139 Layouts/Partials/Layer.vala:687
-msgid "Lock Layer"
-msgstr "Blocca livello"
-
-#: Layouts/Partials/Artboard.vala:155 Layouts/Partials/Artboard.vala:529
-#: Layouts/Partials/Layer.vala:156 Layouts/Partials/Layer.vala:729
-msgid "Hide Layer"
-msgstr "Nascondi livello"
-
-#: Layouts/Partials/Artboard.vala:487 Layouts/Partials/Layer.vala:687
-msgid "Unlock Layer"
-msgstr "Sblocca livello"
-
-#: Layouts/Partials/Artboard.vala:529 Layouts/Partials/Layer.vala:729
-msgid "Show Layer"
-msgstr "Mostra livello"
-
-#: Layouts/Partials/BorderRadiusPanel.vala:86
-msgid "Style"
-msgstr "Stile"
-
-#: Layouts/Partials/BorderRadiusPanel.vala:103
-msgid "Border Radius"
-msgstr "Raggio bordo"
-
-#: Layouts/Partials/BorderRadiusPanel.vala:198
-msgid "Autoscale Corners"
-msgstr "Angoli automaticamente scalati"
-
-#: Layouts/Partials/BorderRadiusPanel.vala:207
-msgid "Uniform Corners"
-msgstr "Angoli uniformati"
-
-#: Layouts/Partials/BordersPanel.vala:53
-msgid "Borders"
-msgstr "Bordi"
-
-#: Layouts/Partials/FillsPanel.vala:54
-msgid "Fills"
-msgstr "Riempi"
-
-#: Layouts/Partials/TransformPanel.vala:96
-msgid "X"
-msgstr "X"
-
-#: Layouts/Partials/TransformPanel.vala:96
-msgid "Horizontal position"
-msgstr "Posizione orizzontale"
-
-#: Layouts/Partials/TransformPanel.vala:98
-msgid "Y"
-msgstr "Y"
-
-#: Layouts/Partials/TransformPanel.vala:98
-msgid "Vertical position"
-msgstr "Posizione verticale"
-
-#: Layouts/Partials/TransformPanel.vala:100
-msgid "W"
-msgstr "W"
-
-#: Layouts/Partials/TransformPanel.vala:100
-msgid "Width"
-msgstr "Larghezza"
-
-#: Layouts/Partials/TransformPanel.vala:102
-msgid "H"
-msgstr "H"
-
-#: Layouts/Partials/TransformPanel.vala:102
-msgid "Height"
-msgstr "Altezza"
-
-#: Layouts/Partials/TransformPanel.vala:107
-msgid "Lock Ratio"
-msgstr "Blocca proporzioni"
-
-#: Layouts/Partials/TransformPanel.vala:114
-msgid "R"
-msgstr "R"
-
-#: Layouts/Partials/TransformPanel.vala:114
-msgid "Rotation degrees"
-msgstr "Angolo di rotazione"
-
-#: Layouts/Partials/TransformPanel.vala:126
-msgid "Flip Horizontally"
-msgstr "Capovolgi orizzontalmente"
-
-#: Layouts/Partials/TransformPanel.vala:137
-msgid "Flip Vertically"
-msgstr "Capovolgi verticalmente"
-
-#: Layouts/Partials/TransformPanel.vala:165
-msgid "Position"
-msgstr "Posizione"
-
-#: Layouts/Partials/TransformPanel.vala:169
-msgid "Size"
-msgstr "Grandezza"
-
-#: Layouts/Partials/TransformPanel.vala:178
-msgid "Opacity"
-msgstr "Opacità"
-
-#: Layouts/RightSideBar.vala:111
-msgid "Search Layer"
-msgstr "Cerca livello"
-
-#: Lib/Managers/ExportManager.vala:192 Lib/Managers/ExportManager.vala:219
-msgid "Generating preview, please wait…"
-msgstr "Generazione dell'anteprima in corso…"
-
-#: Lib/Managers/ExportManager.vala:313
-#, c-format
-msgid "Untitled %i"
-msgstr "Senza titolo %i"
-
-#: Lib/Managers/ExportManager.vala:484
-msgid "Exporting images…"
-msgstr "Esportazione delle immagini in corso…"
-
-#: Partials/ExportWidget.vala:117
-#, c-format
-msgid "%i × %i px · %s"
-msgstr "%i × %i px · %s"
-
-#: Partials/ExportWidget.vala:124
-msgid "Fetching image size…"
-msgstr "Calcolo delle dimensioni dell'immagine in corso…"
-
-#: Partials/ZoomButton.vala:49
-msgid "Zoom Out"
-msgstr "Riduci zoom"
-
-#: Partials/ZoomButton.vala:55
-msgid "Reset Zoom"
-msgstr "Reimposta zoom"
-
-#: Partials/ZoomButton.vala:62
-msgid "Zoom In"
-msgstr "Aumenta zoom"
-
-#: Partials/ZoomButton.vala:68
-msgid "Zoom"
-msgstr "Zoom"
-
-#: Services/ActionManager.vala:211
-msgid "No recently opened file available!"
-msgstr "Nessun file aperto recentemente disponibile!"
-
-#: Services/ActionManager.vala:230
-msgid "No second most recently opened file available!"
-msgstr "Nessun secondo file aperto recentemente disponibile!"
-
-#: Services/ActionManager.vala:249
-msgid "No third most recently opened file available!"
-msgstr "Nessun terzo file aperto recentemente disponibile!"
-
-#: Services/ActionManager.vala:287
-msgid "Nothing selected to export!"
-msgstr "Nessuna selezione da esportare!"
-
-#: Services/ActionManager.vala:296
-msgid "Export of Artboards currently unavailable…sorry 😑️"
-msgstr ""
-"Spiacente, l'esportazione delle artboard non è al momento disponibile 😑️"
-
-#: Services/ActionManager.vala:363
-msgid "Choose image file"
-msgstr "Scegli l'immagine"
-
-#: Services/ActionManager.vala:363
-msgid "Select"
-msgstr "Seleziona"
-
-#: Services/ActionManager.vala:363
-msgid "Close"
-msgstr "Chiudi"
-
-#: Services/ActionManager.vala:432
-#, c-format
-msgid "Error! .%s files are not supported!"
-msgstr "Errore! I file %s non sono supportati."
-
-#: Window.vala:119
-msgid "Are you sure you want to quit?"
-msgstr "Sei sicuro di voler uscire?"
-
-#: Window.vala:120
-msgid "All unsaved data will be lost and impossible to recover."
-msgstr ""
-"Tutti i dati non salvati saranno persi e non sarà possibile recuperarli."
-
-#: Window.vala:122
-msgid "Quit without saving!"
-msgstr "Esci senza salvare!"
-
-#: Window.vala:123
-msgid "Save file"
-msgstr "Salva file"
diff --git a/po/iu.po b/po/iu.po
deleted file mode 100644
index 7d7bf5d53..000000000
--- a/po/iu.po
+++ /dev/null
@@ -1,4 +0,0 @@
-msgid ""
-msgstr ""
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
diff --git a/po/ja.po b/po/ja.po
deleted file mode 100644
index 2f3f844f3..000000000
--- a/po/ja.po
+++ /dev/null
@@ -1,5 +0,0 @@
-msgid ""
-msgstr ""
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
-"Plural-Forms: nplurals=2; plural=n == 1 ? 0 : 1;\n"
diff --git a/po/jv.po b/po/jv.po
deleted file mode 100644
index 7d7bf5d53..000000000
--- a/po/jv.po
+++ /dev/null
@@ -1,4 +0,0 @@
-msgid ""
-msgstr ""
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
diff --git a/po/ka.po b/po/ka.po
deleted file mode 100644
index 7d7bf5d53..000000000
--- a/po/ka.po
+++ /dev/null
@@ -1,4 +0,0 @@
-msgid ""
-msgstr ""
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
diff --git a/po/kg.po b/po/kg.po
deleted file mode 100644
index 7d7bf5d53..000000000
--- a/po/kg.po
+++ /dev/null
@@ -1,4 +0,0 @@
-msgid ""
-msgstr ""
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
diff --git a/po/ki.po b/po/ki.po
deleted file mode 100644
index 7d7bf5d53..000000000
--- a/po/ki.po
+++ /dev/null
@@ -1,4 +0,0 @@
-msgid ""
-msgstr ""
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
diff --git a/po/kj.po b/po/kj.po
deleted file mode 100644
index 7d7bf5d53..000000000
--- a/po/kj.po
+++ /dev/null
@@ -1,4 +0,0 @@
-msgid ""
-msgstr ""
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
diff --git a/po/kk.po b/po/kk.po
deleted file mode 100644
index 7d7bf5d53..000000000
--- a/po/kk.po
+++ /dev/null
@@ -1,4 +0,0 @@
-msgid ""
-msgstr ""
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
diff --git a/po/kl.po b/po/kl.po
deleted file mode 100644
index 7d7bf5d53..000000000
--- a/po/kl.po
+++ /dev/null
@@ -1,4 +0,0 @@
-msgid ""
-msgstr ""
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
diff --git a/po/km.po b/po/km.po
deleted file mode 100644
index 7d7bf5d53..000000000
--- a/po/km.po
+++ /dev/null
@@ -1,4 +0,0 @@
-msgid ""
-msgstr ""
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
diff --git a/po/kn.po b/po/kn.po
deleted file mode 100644
index 7d7bf5d53..000000000
--- a/po/kn.po
+++ /dev/null
@@ -1,4 +0,0 @@
-msgid ""
-msgstr ""
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
diff --git a/po/ko.po b/po/ko.po
deleted file mode 100644
index bb8b6d67d..000000000
--- a/po/ko.po
+++ /dev/null
@@ -1,717 +0,0 @@
-msgid ""
-msgstr ""
-"Project-Id-Version: \n"
-"POT-Creation-Date: 2020-10-07 21:17+0200\n"
-"PO-Revision-Date: 2021-04-05 15:52+0900\n"
-"Last-Translator: 이정희 \n"
-"Language-Team: \n"
-"Language: ko\n"
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
-"Content-Transfer-Encoding: 8bit\n"
-"X-Generator: Poedit 2.4.1\n"
-"X-Poedit-Basepath: .\n"
-"Plural-Forms: nplurals=2; plural=(n > 1);\n"
-"X-Poedit-SearchPath-0: .\n"
-
-#: src/Dialogs/ExportDialog.vala:151
-msgid "Export to:"
-msgstr "다음으로 내보내기:"
-
-#: src/Dialogs/ExportDialog.vala:157
-msgid "Select Folder"
-msgstr "폴더 선택"
-
-#: src/Dialogs/ExportDialog.vala:166
-msgid "Format:"
-msgstr "형식:"
-
-#: src/Dialogs/ExportDialog.vala:179
-msgid "Quality:"
-msgstr "품질:"
-
-#: src/Dialogs/ExportDialog.vala:191
-msgid "Compression:"
-msgstr "압축:"
-
-#: src/Dialogs/ExportDialog.vala:205
-msgid "Transparency:"
-msgstr "투명도:"
-
-#: src/Dialogs/ExportDialog.vala:218
-msgid "Scale:"
-msgstr "크기 조정:"
-
-#: src/Dialogs/ExportDialog.vala:242 src/FileFormat/FileManager.vala:49
-#: src/FileFormat/FileManager.vala:105
-msgid "Cancel"
-msgstr "취소"
-
-#: src/Dialogs/ExportDialog.vala:249 src/Dialogs/ShortcutsDialog.vala:63
-#: src/Layouts/HeaderBar.vala:112
-msgid "Export"
-msgstr "내보내기"
-
-#: src/Dialogs/ReleaseDialog.vala:47 src/Dialogs/SettingsDialog.vala:217
-msgid ""
-"WARNING!\n"
-"Akira is still under development and not ready for production. Missing "
-"features, random bugs, and black holes opening in your kitchen are to be "
-"expected."
-msgstr ""
-"경고!\n"
-"아키라는 아직 개발 중이며 제품 준비가 되지 않았습니다. 누락된 기능, 임의의 "
-"버그 및 부엌에서 열리는 블랙홀이 예상됩니다."
-
-#: src/Dialogs/ReleaseDialog.vala:100 src/Dialogs/SettingsDialog.vala:249
-msgid "Make a Donation"
-msgstr "기부하기"
-
-#: src/Dialogs/ReleaseDialog.vala:109 src/Dialogs/SettingsDialog.vala:258
-msgid "Suggest Translations"
-msgstr "번역 제안"
-
-#: src/Dialogs/ReleaseDialog.vala:118 src/Dialogs/SettingsDialog.vala:267
-msgid "Report a Problem"
-msgstr "문제 보고"
-
-#: src/Dialogs/SettingsDialog.vala:40
-msgid "Preferences"
-msgstr "환경설정"
-
-#: src/Dialogs/SettingsDialog.vala:50 src/Dialogs/SettingsDialog.vala:73
-#: src/Dialogs/ShortcutsDialog.vala:45
-msgid "General"
-msgstr "일반"
-
-#: src/Dialogs/SettingsDialog.vala:51 src/Dialogs/SettingsDialog.vala:86
-msgid "Interface"
-msgstr "인터페이스"
-
-#: src/Dialogs/SettingsDialog.vala:52 src/Layouts/HeaderBar.vala:280
-msgid "Shapes"
-msgstr "모양"
-
-#: src/Dialogs/SettingsDialog.vala:53
-msgid "About"
-msgstr "정보"
-
-#: src/Dialogs/SettingsDialog.vala:74
-msgid "Auto Reopen Latest File:"
-msgstr "최근 파일 자동 다시 열기:"
-
-#: src/Dialogs/SettingsDialog.vala:88
-msgid "Use Dark Theme:"
-msgstr "어두운 테마 사용:"
-
-#: src/Dialogs/SettingsDialog.vala:92
-msgid "Invert Panels Order:"
-msgstr "패널 순서 반전:"
-
-#: src/Dialogs/SettingsDialog.vala:96
-msgid "Restart application to apply this change."
-msgstr "이 변경 내용을 적용하려면 응용 프로그램을 다시 시작하십시오."
-
-#: src/Dialogs/SettingsDialog.vala:100
-msgid "ToolBar Style"
-msgstr "도구모음 스타일"
-
-#: src/Dialogs/SettingsDialog.vala:102
-msgid "Show Button Labels:"
-msgstr "버튼 레이블 표시:"
-
-#: src/Dialogs/SettingsDialog.vala:106
-msgid "Use Symbolic Icons:"
-msgstr "기호 아이콘 사용:"
-
-#: src/Dialogs/SettingsDialog.vala:129
-msgid "Default Colors"
-msgstr "기본 색상"
-
-#: src/Dialogs/SettingsDialog.vala:131
-msgid "Define the default style used when creating a new shape."
-msgstr "새 모양을 만들 때 사용되는 기본 스타일을 정의합니다."
-
-#: src/Dialogs/SettingsDialog.vala:136
-msgid "Fill Color:"
-msgstr "색상 채우기:"
-
-#: src/Dialogs/SettingsDialog.vala:157
-msgid "Enable Border Style:"
-msgstr "테두리 스타일 사용:"
-
-#: src/Dialogs/SettingsDialog.vala:160
-msgid "Border Color:"
-msgstr "테두리 색상:"
-
-#: src/Dialogs/SettingsDialog.vala:181
-msgid "Border Width:"
-msgstr "테두리 너비:"
-
-#: src/Dialogs/SettingsDialog.vala:209
-msgid "The Linux Design Tool"
-msgstr "리눅스 디자인 도구"
-
-#: src/Dialogs/SettingsDialog.vala:226
-msgid "Thanks to our awesome supporters!"
-msgstr "멋진 서포터들에게 감사드립니다!"
-
-#: src/Dialogs/SettingsDialog.vala:231
-msgid "View the list of supporters"
-msgstr "서포터 목록보기"
-
-#: src/Dialogs/ShortcutsDialog.vala:46
-msgid "New window:"
-msgstr "새 창:"
-
-#: src/Dialogs/ShortcutsDialog.vala:48
-msgid "Preferences:"
-msgstr "환경설정:"
-
-#: src/Dialogs/ShortcutsDialog.vala:50
-msgid "Quit:"
-msgstr "종료:"
-
-#: src/Dialogs/ShortcutsDialog.vala:52
-msgid "Presentation mode:"
-msgstr "프레젠테이션 모드:"
-
-#: src/Dialogs/ShortcutsDialog.vala:55
-msgid "File"
-msgstr "파일"
-
-#: src/Dialogs/ShortcutsDialog.vala:56
-msgid "Open:"
-msgstr "열기:"
-
-#: src/Dialogs/ShortcutsDialog.vala:58
-msgid "Save:"
-msgstr "저장:"
-
-#: src/Dialogs/ShortcutsDialog.vala:60
-msgid "Save as:"
-msgstr "다른 이름으로 저장:"
-
-#: src/Dialogs/ShortcutsDialog.vala:64
-msgid "Export artboards:"
-msgstr "아트보드 내보내기:"
-
-#: src/Dialogs/ShortcutsDialog.vala:66
-msgid "Export selection:"
-msgstr "내보내기 선택:"
-
-#: src/Dialogs/ShortcutsDialog.vala:68
-msgid "Highlight area to export:"
-msgstr "내보낼 영역 강조표시:"
-
-#: src/Dialogs/ShortcutsDialog.vala:77
-msgid "Canvas"
-msgstr "캔버스"
-
-#: src/Dialogs/ShortcutsDialog.vala:78
-msgid "Zoom in:"
-msgstr "확대:"
-
-#: src/Dialogs/ShortcutsDialog.vala:80
-msgid "Zoom out:"
-msgstr "축소:"
-
-#: src/Dialogs/ShortcutsDialog.vala:82
-msgid "Zoom reset:"
-msgstr "확대/축소 재설정"
-
-#: src/Dialogs/ShortcutsDialog.vala:85
-msgid "Item creation"
-msgstr "항목 만들기"
-
-#: src/Dialogs/ShortcutsDialog.vala:86
-msgid "Artboard:"
-msgstr "아트보드:"
-
-#: src/Dialogs/ShortcutsDialog.vala:88
-msgid "Rectangle:"
-msgstr "직사각형:"
-
-#: src/Dialogs/ShortcutsDialog.vala:90
-msgid "Ellipse:"
-msgstr "타원형:"
-
-#: src/Dialogs/ShortcutsDialog.vala:92
-msgid "Text:"
-msgstr "텍스트:"
-
-#: src/Dialogs/ShortcutsDialog.vala:94
-msgid "Image:"
-msgstr "이미지:"
-
-#: src/Dialogs/ShortcutsDialog.vala:97
-#: src/Layouts/Partials/TransformPanel.vala:174
-msgid "Transform"
-msgstr "변환"
-
-#: src/Dialogs/ShortcutsDialog.vala:98
-msgid "Raise selection:"
-msgstr "선택 항목 올리기:"
-
-#: src/Dialogs/ShortcutsDialog.vala:100
-msgid "Lower selection:"
-msgstr "선택 항목 내리기:"
-
-#: src/Dialogs/ShortcutsDialog.vala:102
-msgid "Raise selection to top:"
-msgstr "선택 항목을 맨 위로 올리기 :"
-
-#: src/Dialogs/ShortcutsDialog.vala:104
-msgid "Lower selection to bottom:"
-msgstr "선택 항목을 맨 아래로 내리기:"
-
-#: src/Dialogs/ShortcutsDialog.vala:106
-msgid "Flip horizontally:"
-msgstr "수평으로 뒤집기:"
-
-#: src/Dialogs/ShortcutsDialog.vala:108
-msgid "Flip vertically:"
-msgstr "수직으로 뒤집기:"
-
-#: src/FileFormat/FileManager.vala:46
-msgid "Save Akira file"
-msgstr "아키라 파일 저장"
-
-#: src/FileFormat/FileManager.vala:48 src/Layouts/HeaderBar.vala:190
-msgid "Save"
-msgstr "저장"
-
-#: src/FileFormat/FileManager.vala:71
-msgid "Akira files"
-msgstr "아키라 파일"
-
-#: src/FileFormat/FileManager.vala:76
-msgid "All files"
-msgstr "모든 파일"
-
-#: src/FileFormat/FileManager.vala:103
-msgid "Open Akira file"
-msgstr "아키라 파일 열기"
-
-#: src/FileFormat/FileManager.vala:105 src/Layouts/HeaderBar.vala:170
-msgid "Open"
-msgstr "열기"
-
-#: src/Layouts/HeaderBar.vala:69 src/Lib/Managers/ExportManager.vala:296
-msgid "Untitled"
-msgstr "제목 없음"
-
-#: src/Layouts/HeaderBar.vala:71
-msgid "Menu"
-msgstr "메뉴"
-
-#: src/Layouts/HeaderBar.vala:75
-msgid "Insert"
-msgstr "삽입"
-
-#: src/Layouts/HeaderBar.vala:82
-msgid "Group"
-msgstr "그룹"
-
-#: src/Layouts/HeaderBar.vala:84
-msgid "Ungroup"
-msgstr "그룹 해제"
-
-#: src/Layouts/HeaderBar.vala:87
-msgid "Up"
-msgstr "위로"
-
-#: src/Layouts/HeaderBar.vala:92
-msgid "Down"
-msgstr "아래로"
-
-#: src/Layouts/HeaderBar.vala:97
-msgid "Top"
-msgstr "맨 위로"
-
-#: src/Layouts/HeaderBar.vala:102
-msgid "Bottom"
-msgstr "맨 아래로"
-
-#: src/Layouts/HeaderBar.vala:107
-msgid "Settings"
-msgstr "설정"
-
-#: src/Layouts/HeaderBar.vala:118
-msgid "Difference"
-msgstr "차이"
-
-#: src/Layouts/HeaderBar.vala:120
-msgid "Exclusion"
-msgstr "제외"
-
-#: src/Layouts/HeaderBar.vala:122
-msgid "Intersect"
-msgstr "교차"
-
-#: src/Layouts/HeaderBar.vala:124
-msgid "Union"
-msgstr "결합"
-
-#: src/Layouts/HeaderBar.vala:161
-msgid "New Window"
-msgstr "새 창"
-
-#: src/Layouts/HeaderBar.vala:182
-msgid "Open Recent"
-msgstr "최근 파일 열기"
-
-#: src/Layouts/HeaderBar.vala:195
-msgid "Save As"
-msgstr "다른 이름으로 저장"
-
-#: src/Layouts/HeaderBar.vala:204
-msgid "Quit"
-msgstr "종료"
-
-#: src/Layouts/HeaderBar.vala:237
-msgid "Artboard"
-msgstr "아트보드"
-
-#: src/Layouts/HeaderBar.vala:254
-msgid "Add Items"
-msgstr "항목 추가"
-
-#: src/Layouts/HeaderBar.vala:262
-msgid "Rectangle"
-msgstr "직사각"
-
-#: src/Layouts/HeaderBar.vala:268
-msgid "Ellipse"
-msgstr "타원"
-
-#: src/Layouts/HeaderBar.vala:286
-msgid "Vector"
-msgstr "벡터"
-
-#: src/Layouts/HeaderBar.vala:288
-msgid "Pencil"
-msgstr "연필"
-
-#: src/Layouts/HeaderBar.vala:291
-msgid "Text"
-msgstr "텍스트"
-
-#: src/Layouts/HeaderBar.vala:297
-msgid "Image"
-msgstr "이미지"
-
-#: src/Layouts/HeaderBar.vala:330
-msgid "Export Current Selection"
-msgstr "현재 선택 내보내기"
-
-#: src/Layouts/HeaderBar.vala:336
-msgid "Export Artboards"
-msgstr "아트보드 내보내기"
-
-#: src/Layouts/HeaderBar.vala:345
-msgid "Highlight Area to Export"
-msgstr "내보낼 영역 강조 표시"
-
-#: src/Layouts/HeaderBar.vala:391
-msgid "Main Menu"
-msgstr "기본 메뉴"
-
-#: src/Layouts/HeaderBar.vala:468 src/Services/ActionManager.vala:224
-#: src/Services/ActionManager.vala:243 src/Services/ActionManager.vala:262
-#, c-format
-msgid "Unable to open file at '%s'"
-msgstr "'%s'에서 파일을 열 수 없습니다."
-
-#: src/Layouts/MainCanvas.vala:46
-msgid "Button was pressed!"
-msgstr "버튼을 눌렀습니다!"
-
-#: src/Layouts/MainCanvas.vala:206
-msgid "Export completed!"
-msgstr "내보내기 완료!"
-
-#: src/Layouts/Partials/AlignItemsPanel.vala:48
-msgid "Distribute Horizontally"
-msgstr "수평으로 분배"
-
-#: src/Layouts/Partials/AlignItemsPanel.vala:50
-msgid "Distribute Vertically"
-msgstr "수직으로 분배"
-
-#: src/Layouts/Partials/AlignItemsPanel.vala:52
-msgid "Align Left"
-msgstr "왼쪽 정렬"
-
-#: src/Layouts/Partials/AlignItemsPanel.vala:53
-msgid "Align Center"
-msgstr "가운데 정렬"
-
-#: src/Layouts/Partials/AlignItemsPanel.vala:54
-msgid "Align Right"
-msgstr "오른쪽 정렬"
-
-#: src/Layouts/Partials/AlignItemsPanel.vala:56
-msgid "Align Top"
-msgstr "상단 정렬"
-
-#: src/Layouts/Partials/AlignItemsPanel.vala:57
-msgid "Align Middle"
-msgstr "중간 정렬"
-
-#: src/Layouts/Partials/AlignItemsPanel.vala:58
-msgid "Align Bottom"
-msgstr "하단 정렬"
-
-#: src/Layouts/Partials/Artboard.vala:144
-#: src/Layouts/Partials/Artboard.vala:487 src/Layouts/Partials/Layer.vala:139
-#: src/Layouts/Partials/Layer.vala:687
-msgid "Lock Layer"
-msgstr "레이어 잠금"
-
-#: src/Layouts/Partials/Artboard.vala:155
-#: src/Layouts/Partials/Artboard.vala:529 src/Layouts/Partials/Layer.vala:156
-#: src/Layouts/Partials/Layer.vala:729
-msgid "Hide Layer"
-msgstr "레이어 숨김"
-
-#: src/Layouts/Partials/Artboard.vala:487 src/Layouts/Partials/Layer.vala:687
-msgid "Unlock Layer"
-msgstr "레이어 잠금 해제"
-
-#: src/Layouts/Partials/Artboard.vala:529 src/Layouts/Partials/Layer.vala:729
-msgid "Show Layer"
-msgstr "레이어 표시"
-
-#: src/Layouts/Partials/BorderItem.vala:121
-msgid "Choose border color"
-msgstr "테두리 색상 선택"
-
-#: src/Layouts/Partials/BorderItem.vala:176
-#: src/Layouts/Partials/FillItem.vala:178
-msgid "Pick color"
-msgstr "색상 선택"
-
-#: src/Layouts/Partials/BorderItem.vala:191
-msgid "Remove border"
-msgstr "테두리 제거"
-
-#: src/Layouts/Partials/BorderItem.vala:275
-msgid "Show border"
-msgstr "테두리 표시"
-
-#: src/Layouts/Partials/BorderItem.vala:279
-msgid "Hide border"
-msgstr "테두리 숨김"
-
-#: src/Layouts/Partials/BorderRadiusPanel.vala:86
-msgid "Style"
-msgstr "스타일"
-
-#: src/Layouts/Partials/BorderRadiusPanel.vala:103
-msgid "Border Radius"
-msgstr "테두리 반경"
-
-#: src/Layouts/Partials/BorderRadiusPanel.vala:137
-msgid "Border radius options"
-msgstr "테두리 반경 옵션"
-
-#: src/Layouts/Partials/BorderRadiusPanel.vala:199
-msgid "Autoscale Corners"
-msgstr "모서리 자동 크기조정"
-
-#: src/Layouts/Partials/BorderRadiusPanel.vala:208
-msgid "Uniform Corners"
-msgstr "균일한 모서리"
-
-#: src/Layouts/Partials/BordersPanel.vala:53
-msgid "Borders"
-msgstr "테두리"
-
-#: src/Layouts/Partials/BordersPanel.vala:64
-msgid "Add border"
-msgstr "테두리 추가"
-
-#: src/Layouts/Partials/FillItem.vala:114
-msgid "Choose fill color"
-msgstr "채우기 색상 선택"
-
-#: src/Layouts/Partials/FillItem.vala:193
-msgid "Remove fill color"
-msgstr "채우기 색상 제거"
-
-#: src/Layouts/Partials/FillItem.vala:277
-msgid "Show fill color"
-msgstr "채우기 색상 표시"
-
-#: src/Layouts/Partials/FillItem.vala:281
-msgid "Hide fill color"
-msgstr "채우기 색상 숨김"
-
-#: src/Layouts/Partials/FillsPanel.vala:54
-msgid "Fills"
-msgstr "채우기"
-
-#: src/Layouts/Partials/FillsPanel.vala:65
-msgid "Add fill color"
-msgstr "채우기 색상 추가"
-
-#: src/Layouts/Partials/TransformPanel.vala:96
-msgid "X"
-msgstr "X"
-
-#: src/Layouts/Partials/TransformPanel.vala:96
-msgid "Horizontal position"
-msgstr "수평 위치"
-
-#: src/Layouts/Partials/TransformPanel.vala:98
-msgid "Y"
-msgstr "Y"
-
-#: src/Layouts/Partials/TransformPanel.vala:98
-msgid "Vertical position"
-msgstr "수직 위치"
-
-#: src/Layouts/Partials/TransformPanel.vala:100
-msgid "W"
-msgstr "W"
-
-#: src/Layouts/Partials/TransformPanel.vala:100
-msgid "Width"
-msgstr "너비"
-
-#: src/Layouts/Partials/TransformPanel.vala:102
-msgid "H"
-msgstr "H"
-
-#: src/Layouts/Partials/TransformPanel.vala:102
-msgid "Height"
-msgstr "높이"
-
-#: src/Layouts/Partials/TransformPanel.vala:107
-msgid "Lock Ratio"
-msgstr "비율 잠금"
-
-#: src/Layouts/Partials/TransformPanel.vala:114
-msgid "R"
-msgstr "R"
-
-#: src/Layouts/Partials/TransformPanel.vala:114
-msgid "Rotation degrees"
-msgstr "회전 각도"
-
-#: src/Layouts/Partials/TransformPanel.vala:126
-msgid "Flip Horizontally"
-msgstr "수평으로 뒤집기"
-
-#: src/Layouts/Partials/TransformPanel.vala:137
-msgid "Flip Vertically"
-msgstr "수직으로 뒤집기"
-
-#: src/Layouts/Partials/TransformPanel.vala:165
-msgid "Position"
-msgstr "위치"
-
-#: src/Layouts/Partials/TransformPanel.vala:169
-msgid "Size"
-msgstr "크기"
-
-#: src/Layouts/Partials/TransformPanel.vala:178
-msgid "Opacity"
-msgstr "불투명도"
-
-#: src/Layouts/RightSideBar.vala:111
-msgid "Search Layer"
-msgstr "레이어 검색"
-
-#: src/Lib/Managers/ExportManager.vala:192
-#: src/Lib/Managers/ExportManager.vala:219
-msgid "Generating preview, please wait…"
-msgstr "미리보기를 생성하는 중입니다. 잠시 기다려주세요…"
-
-#: src/Lib/Managers/ExportManager.vala:313
-#, c-format
-msgid "Untitled %i"
-msgstr "%i 제목 없음"
-
-#: src/Lib/Managers/ExportManager.vala:484
-msgid "Exporting images…"
-msgstr "이미지 내보내는 중…"
-
-#: src/Partials/ExportWidget.vala:117
-#, c-format
-msgid "%i × %i px · %s"
-msgstr "%i × %i px · %s"
-
-#: src/Partials/ExportWidget.vala:124
-msgid "Fetching image size…"
-msgstr "이미지 크기 가져오는 중..."
-
-#: src/Partials/ZoomButton.vala:49
-msgid "Zoom Out"
-msgstr "축소"
-
-#: src/Partials/ZoomButton.vala:55
-msgid "Reset Zoom"
-msgstr "확대/축소 재설정"
-
-#: src/Partials/ZoomButton.vala:62
-msgid "Zoom In"
-msgstr "확대"
-
-#: src/Partials/ZoomButton.vala:68
-msgid "Zoom"
-msgstr "확대/축소"
-
-#: src/Services/ActionManager.vala:217
-msgid "No recently opened file available!"
-msgstr "최근에 연 파일을 사용할 수 없습니다!"
-
-#: src/Services/ActionManager.vala:236
-msgid "No second most recently opened file available!"
-msgstr "두 번째로 가장 최근에 연 파일을 사용할 수 없습니다!"
-
-#: src/Services/ActionManager.vala:255
-msgid "No third most recently opened file available!"
-msgstr "세 번째로 가장 최근에 연 파일을 사용할 수 없습니다!"
-
-#: src/Services/ActionManager.vala:293
-msgid "Nothing selected to export!"
-msgstr "내보낼 항목을 선택하지 않았습니다!"
-
-#: src/Services/ActionManager.vala:302
-msgid "Export of Artboards currently unavailable…sorry 😑️"
-msgstr "현재 아트보드 내보내기를 사용할 수 없습니다... 미안해요 😑️"
-
-#: src/Services/ActionManager.vala:373
-msgid "Choose image file"
-msgstr "이미지 파일 선택"
-
-#: src/Services/ActionManager.vala:373
-msgid "Select"
-msgstr "선택"
-
-#: src/Services/ActionManager.vala:373
-msgid "Close"
-msgstr "닫기"
-
-#: src/Services/ActionManager.vala:442
-#, c-format
-msgid "Error! .%s files are not supported!"
-msgstr "오류! .%s 파일은 지원되지 않습니다!"
-
-#: src/Window.vala:121
-msgid "Are you sure you want to quit?"
-msgstr "종료 하시겠습니까?"
-
-#: src/Window.vala:122
-msgid "All unsaved data will be lost and impossible to recover."
-msgstr "저장되지 않은 모든 데이터는 손실되고 복구할 수 없습니다."
-
-#: src/Window.vala:124
-msgid "Quit without saving!"
-msgstr "저장하지 않고 종료!"
-
-#: src/Window.vala:125
-msgid "Save file"
-msgstr "파일 저장"
diff --git a/po/kr.po b/po/kr.po
deleted file mode 100644
index 7d7bf5d53..000000000
--- a/po/kr.po
+++ /dev/null
@@ -1,4 +0,0 @@
-msgid ""
-msgstr ""
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
diff --git a/po/ks.po b/po/ks.po
deleted file mode 100644
index 7d7bf5d53..000000000
--- a/po/ks.po
+++ /dev/null
@@ -1,4 +0,0 @@
-msgid ""
-msgstr ""
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
diff --git a/po/ku.po b/po/ku.po
deleted file mode 100644
index 7d7bf5d53..000000000
--- a/po/ku.po
+++ /dev/null
@@ -1,4 +0,0 @@
-msgid ""
-msgstr ""
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
diff --git a/po/kv.po b/po/kv.po
deleted file mode 100644
index 7d7bf5d53..000000000
--- a/po/kv.po
+++ /dev/null
@@ -1,4 +0,0 @@
-msgid ""
-msgstr ""
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
diff --git a/po/kw.po b/po/kw.po
deleted file mode 100644
index 7d7bf5d53..000000000
--- a/po/kw.po
+++ /dev/null
@@ -1,4 +0,0 @@
-msgid ""
-msgstr ""
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
diff --git a/po/ky.po b/po/ky.po
deleted file mode 100644
index 7d7bf5d53..000000000
--- a/po/ky.po
+++ /dev/null
@@ -1,4 +0,0 @@
-msgid ""
-msgstr ""
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
diff --git a/po/la.po b/po/la.po
deleted file mode 100644
index 7d7bf5d53..000000000
--- a/po/la.po
+++ /dev/null
@@ -1,4 +0,0 @@
-msgid ""
-msgstr ""
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
diff --git a/po/lb.po b/po/lb.po
deleted file mode 100644
index 7d7bf5d53..000000000
--- a/po/lb.po
+++ /dev/null
@@ -1,4 +0,0 @@
-msgid ""
-msgstr ""
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
diff --git a/po/lg.po b/po/lg.po
deleted file mode 100644
index 7d7bf5d53..000000000
--- a/po/lg.po
+++ /dev/null
@@ -1,4 +0,0 @@
-msgid ""
-msgstr ""
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
diff --git a/po/li.po b/po/li.po
deleted file mode 100644
index 7d7bf5d53..000000000
--- a/po/li.po
+++ /dev/null
@@ -1,4 +0,0 @@
-msgid ""
-msgstr ""
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
diff --git a/po/ln.po b/po/ln.po
deleted file mode 100644
index 7d7bf5d53..000000000
--- a/po/ln.po
+++ /dev/null
@@ -1,4 +0,0 @@
-msgid ""
-msgstr ""
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
diff --git a/po/lo.po b/po/lo.po
deleted file mode 100644
index 7d7bf5d53..000000000
--- a/po/lo.po
+++ /dev/null
@@ -1,4 +0,0 @@
-msgid ""
-msgstr ""
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
diff --git a/po/lt.po b/po/lt.po
deleted file mode 100644
index d80210d2b..000000000
--- a/po/lt.po
+++ /dev/null
@@ -1,5 +0,0 @@
-msgid ""
-msgstr ""
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
-"Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && (n%100<10 || n%100>=20) ? 1 : 2;\n"
diff --git a/po/lu.po b/po/lu.po
deleted file mode 100644
index 7d7bf5d53..000000000
--- a/po/lu.po
+++ /dev/null
@@ -1,4 +0,0 @@
-msgid ""
-msgstr ""
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
diff --git a/po/lv.po b/po/lv.po
deleted file mode 100644
index 72a9a4c3e..000000000
--- a/po/lv.po
+++ /dev/null
@@ -1,5 +0,0 @@
-msgid ""
-msgstr ""
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
-"Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n != 0 ? 1 : 2;\n"
diff --git a/po/meson.build b/po/meson.build
deleted file mode 100644
index 57d1266b3..000000000
--- a/po/meson.build
+++ /dev/null
@@ -1 +0,0 @@
-i18n.gettext(gettext_package, preset: 'glib')
diff --git a/po/mg.po b/po/mg.po
deleted file mode 100644
index 7d7bf5d53..000000000
--- a/po/mg.po
+++ /dev/null
@@ -1,4 +0,0 @@
-msgid ""
-msgstr ""
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
diff --git a/po/mh.po b/po/mh.po
deleted file mode 100644
index 7d7bf5d53..000000000
--- a/po/mh.po
+++ /dev/null
@@ -1,4 +0,0 @@
-msgid ""
-msgstr ""
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
diff --git a/po/mi.po b/po/mi.po
deleted file mode 100644
index 7d7bf5d53..000000000
--- a/po/mi.po
+++ /dev/null
@@ -1,4 +0,0 @@
-msgid ""
-msgstr ""
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
diff --git a/po/mk.po b/po/mk.po
deleted file mode 100644
index 7d7bf5d53..000000000
--- a/po/mk.po
+++ /dev/null
@@ -1,4 +0,0 @@
-msgid ""
-msgstr ""
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
diff --git a/po/ml.po b/po/ml.po
deleted file mode 100644
index 26ea173ec..000000000
--- a/po/ml.po
+++ /dev/null
@@ -1,711 +0,0 @@
-msgid ""
-msgstr ""
-"Project-Id-Version: \n"
-"POT-Creation-Date: 2020-09-27 19:02+0300\n"
-"PO-Revision-Date: \n"
-"Language-Team: \n"
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
-"Plural-Forms: nplurals=2; plural=n != 1;\n"
-"Content-Transfer-Encoding: 8bit\n"
-"Plural-Forms: nplurals=2; plural=(n != 1);\n"
-"X-Generator: Poedit 2.3\n"
-"X-Poedit-Basepath: ../src\n"
-"Language: ml\n"
-"Last-Translator: \n"
-"X-Poedit-SearchPath-0: .\n"
-
-#: Dialogs/ExportDialog.vala:151
-msgid "Export to:"
-msgstr "കയറ്റുമതി ചെയ്യുക:"
-
-#: Dialogs/ExportDialog.vala:157
-msgid "Select Folder"
-msgstr "ഫോള്ഡര് തിരഞ്ഞെടുക്കുക"
-
-#: Dialogs/ExportDialog.vala:166
-msgid "Format:"
-msgstr "തരം:"
-
-#: Dialogs/ExportDialog.vala:179
-msgid "Quality:"
-msgstr "മേന്മ:"
-
-#: Dialogs/ExportDialog.vala:191
-msgid "Compression:"
-msgstr "ചുരുക്കല്:"
-
-#: Dialogs/ExportDialog.vala:205
-msgid "Transparency:"
-msgstr "സുതാര്യത:"
-
-#: Dialogs/ExportDialog.vala:218
-msgid "Scale:"
-msgstr "തോത്:"
-
-#: Dialogs/ExportDialog.vala:242 FileFormat/FileManager.vala:49
-#: FileFormat/FileManager.vala:105
-msgid "Cancel"
-msgstr "റദ്ദാക്കുക"
-
-#: Dialogs/ExportDialog.vala:249 Dialogs/ShortcutsDialog.vala:63 Layouts/HeaderBar.vala:112
-msgid "Export"
-msgstr "കയറ്റുമതി"
-
-#: Dialogs/ReleaseDialog.vala:47 Dialogs/SettingsDialog.vala:217
-msgid ""
-"WARNING!\n"
-"Akira is still under development and not ready for production. Missing features, random "
-"bugs, and black holes opening in your kitchen are to be expected."
-msgstr ""
-"മുന്നറിയിപ്പ്\n"
-"ജോലിക്കുപാകത്തിന് അകിര ഇനിയും പണിതു തീര്ന്നിട്ടില്ല. സൗകര്യക്കുറവുകളും തുടരെത്തടസ്സങ്ങളും അടുക്കള കാലിയാക്കുന്ന "
-"തമോഗര്ത്തങ്ങള് വരെയും പ്രതീക്ഷിക്കാം."
-
-#: Dialogs/ReleaseDialog.vala:100 Dialogs/SettingsDialog.vala:249
-msgid "Make a Donation"
-msgstr "സംഭാവന നല്കുക"
-
-#: Dialogs/ReleaseDialog.vala:109 Dialogs/SettingsDialog.vala:258
-msgid "Suggest Translations"
-msgstr "തര്ജ്ജമ നിര്ദ്ദേശിക്കുക"
-
-#: Dialogs/ReleaseDialog.vala:118 Dialogs/SettingsDialog.vala:267
-msgid "Report a Problem"
-msgstr "പ്രശ്നങ്ങള് അറിയിക്കുക"
-
-#: Dialogs/SettingsDialog.vala:40
-msgid "Preferences"
-msgstr "സജ്ജീകരണങ്ങള്"
-
-#: Dialogs/SettingsDialog.vala:50 Dialogs/SettingsDialog.vala:73
-#: Dialogs/ShortcutsDialog.vala:45
-msgid "General"
-msgstr "പൊതുസജ്ജീകരങ്ങള്"
-
-#: Dialogs/SettingsDialog.vala:51 Dialogs/SettingsDialog.vala:86
-msgid "Interface"
-msgstr "ദൃശ്യമുഖം"
-
-#: Dialogs/SettingsDialog.vala:52 Layouts/HeaderBar.vala:280
-msgid "Shapes"
-msgstr "രൂപങ്ങള്"
-
-#: Dialogs/SettingsDialog.vala:53
-msgid "About"
-msgstr "സംബന്ധിച്ച്"
-
-#: Dialogs/SettingsDialog.vala:74
-msgid "Auto Reopen Latest File:"
-msgstr "പുതിയ രേഖ താനേ തുറക്കുക:"
-
-#: Dialogs/SettingsDialog.vala:88
-msgid "Use Dark Theme:"
-msgstr "ഇരുണ്ട അലങ്കാരങ്ങള് ഉപയോഗിക്കുക:"
-
-#: Dialogs/SettingsDialog.vala:92
-msgid "Invert Panels Order:"
-msgstr "പാനലുകള് വിപരീതക്രമത്തിലാക്കുക:"
-
-#: Dialogs/SettingsDialog.vala:96
-msgid "Restart application to apply this change."
-msgstr "മാറ്റം നടപ്പിലാക്കാനായി അകിര പുനര്പ്രവര്ത്തിപ്പിക്കുക."
-
-#: Dialogs/SettingsDialog.vala:100
-msgid "ToolBar Style"
-msgstr "ഉപകരണത്തട്ടിന്റെ രൂപം"
-
-#: Dialogs/SettingsDialog.vala:102
-msgid "Show Button Labels:"
-msgstr "ബട്ടണില് എഴുത്തുകള് കാണിക്കുക:"
-
-#: Dialogs/SettingsDialog.vala:106
-msgid "Use Symbolic Icons:"
-msgstr "പ്രതീകാത്മക ചിന്ഹങ്ങള് ഉപയോഗിക്കുക:"
-
-#: Dialogs/SettingsDialog.vala:129
-msgid "Default Colors"
-msgstr "തനത് നിറങ്ങള്"
-
-#: Dialogs/SettingsDialog.vala:131
-msgid "Define the default style used when creating a new shape."
-msgstr "രൂപം വരയ്ക്കുമ്പോള് ഉപയോഗിക്കേണ്ട തനത് ഭംഗി നിര്വചിക്കുക."
-
-#: Dialogs/SettingsDialog.vala:136
-msgid "Fill Color:"
-msgstr "അകനിറം:"
-
-#: Dialogs/SettingsDialog.vala:157
-msgid "Enable Border Style:"
-msgstr "അതിര് ഭംഗി വേണം:"
-
-#: Dialogs/SettingsDialog.vala:160
-msgid "Border Color:"
-msgstr "അതിര്നിറം:"
-
-#: Dialogs/SettingsDialog.vala:181
-msgid "Border Width:"
-msgstr "അതിര്വീതി:"
-
-#: Dialogs/SettingsDialog.vala:209
-msgid "The Linux Design Tool"
-msgstr "ലിനക്സിനു വേണ്ടിയുള്ള രൂപകല്പ്പനാതന്ത്രം"
-
-#: Dialogs/SettingsDialog.vala:226
-msgid "Thanks to our awesome supporters!"
-msgstr "ഞങ്ങളെ പിന്താങ്ങുന്നവര്ക്ക് നന്ദി!"
-
-#: Dialogs/SettingsDialog.vala:231
-msgid "View the list of supporters"
-msgstr "ദാതാക്കളുടെ പട്ടിക കാണുക"
-
-#: Dialogs/ShortcutsDialog.vala:46
-msgid "New window:"
-msgstr "പുതിയ ജാലകം:"
-
-#: Dialogs/ShortcutsDialog.vala:48
-msgid "Preferences:"
-msgstr "സജ്ജീകരണങ്ങള്:"
-
-#: Dialogs/ShortcutsDialog.vala:50
-msgid "Quit:"
-msgstr "പുറത്തിരങ്ങുക:"
-
-#: Dialogs/ShortcutsDialog.vala:52
-msgid "Presentation mode:"
-msgstr "അവതരണ രൂപം:"
-
-#: Dialogs/ShortcutsDialog.vala:55
-msgid "File"
-msgstr "രേഖ"
-
-#: Dialogs/ShortcutsDialog.vala:56
-msgid "Open:"
-msgstr "തുറക്കുക:"
-
-#: Dialogs/ShortcutsDialog.vala:58
-msgid "Save:"
-msgstr "സൂക്ഷിക്കുക:"
-
-#: Dialogs/ShortcutsDialog.vala:60
-msgid "Save as:"
-msgstr "മറ്റൊന്നായി സൂക്ഷിക്കുക:"
-
-#: Dialogs/ShortcutsDialog.vala:64
-msgid "Export artboards:"
-msgstr "കലാഫലകങ്ങള് കയറ്റുമതി ചെയ്യുക:"
-
-#: Dialogs/ShortcutsDialog.vala:66
-msgid "Export selection:"
-msgstr "തിരഞ്ഞെടുത്തത് സൂക്ഷിക്കുക:"
-
-#: Dialogs/ShortcutsDialog.vala:68
-msgid "Highlight area to export:"
-msgstr "കയറ്റുമതി ചെയ്യേണ്ടിടം എടുത്തുകാട്ടുക:"
-
-#: Dialogs/ShortcutsDialog.vala:77
-msgid "Canvas"
-msgstr "ചിത്രത്തുണി"
-
-#: Dialogs/ShortcutsDialog.vala:78
-msgid "Zoom in:"
-msgstr "വലുതാക്കുക:"
-
-#: Dialogs/ShortcutsDialog.vala:80
-msgid "Zoom out:"
-msgstr "ചെറുതാക്കുക:"
-
-#: Dialogs/ShortcutsDialog.vala:82
-msgid "Zoom reset:"
-msgstr "പഴയ വലുപ്പത്തിലാക്കുക:"
-
-#: Dialogs/ShortcutsDialog.vala:85
-msgid "Item creation"
-msgstr "വസ്തു നിര്മാണം"
-
-#: Dialogs/ShortcutsDialog.vala:86
-msgid "Artboard:"
-msgstr "കലാഫലകം:"
-
-#: Dialogs/ShortcutsDialog.vala:88
-msgid "Rectangle:"
-msgstr "ചതുരം:"
-
-#: Dialogs/ShortcutsDialog.vala:90
-msgid "Ellipse:"
-msgstr "വട്ടം:"
-
-#: Dialogs/ShortcutsDialog.vala:92
-msgid "Text:"
-msgstr "എഴുത്ത്:"
-
-#: Dialogs/ShortcutsDialog.vala:94
-msgid "Image:"
-msgstr "ചിത്രം:"
-
-#: Dialogs/ShortcutsDialog.vala:97 Layouts/Partials/TransformPanel.vala:174
-msgid "Transform"
-msgstr "മാറ്റുക"
-
-#: Dialogs/ShortcutsDialog.vala:98
-msgid "Raise selection:"
-msgstr "തിരഞ്ഞെടുത്തത് പൊക്കുക:"
-
-#: Dialogs/ShortcutsDialog.vala:100
-msgid "Lower selection:"
-msgstr "തിരഞ്ഞെടുത്തത് താഴ്ത്തുക:"
-
-#: Dialogs/ShortcutsDialog.vala:102
-msgid "Raise selection to top:"
-msgstr "തിരഞ്ഞെടുത്തത് ഏറ്റവും മുകളിലാക്കുക:"
-
-#: Dialogs/ShortcutsDialog.vala:104
-msgid "Lower selection to bottom:"
-msgstr "തിരഞ്ഞെടുത്തത് ഏറ്റവും അടിയിലാക്കുക:"
-
-#: Dialogs/ShortcutsDialog.vala:106
-msgid "Flip horizontally:"
-msgstr "വിലങ്ങനെ മറിക്കുക:"
-
-#: Dialogs/ShortcutsDialog.vala:108
-msgid "Flip vertically:"
-msgstr "കുത്തനെ മറിക്കുക:"
-
-#: FileFormat/FileManager.vala:46
-msgid "Save Akira file"
-msgstr "അകിര രേഖയാക്കി സൂക്ഷിക്കുക"
-
-#: FileFormat/FileManager.vala:48 Layouts/HeaderBar.vala:190
-msgid "Save"
-msgstr "സുക്ഷിക്കുക"
-
-#: FileFormat/FileManager.vala:71
-msgid "Akira files"
-msgstr "അകിര രേഖക"
-
-#: FileFormat/FileManager.vala:76
-msgid "All files"
-msgstr "എല്ലാ രേഖകളും"
-
-#: FileFormat/FileManager.vala:103
-msgid "Open Akira file"
-msgstr "ഒരു അകിര രേഖ തുറക്കുക"
-
-#: FileFormat/FileManager.vala:105 Layouts/HeaderBar.vala:170
-msgid "Open"
-msgstr "തുറക്കുക"
-
-#: Layouts/HeaderBar.vala:69 Lib/Managers/ExportManager.vala:296
-msgid "Untitled"
-msgstr "പേരില്ലാത്തത്"
-
-#: Layouts/HeaderBar.vala:71
-msgid "Menu"
-msgstr "മെനു"
-
-#: Layouts/HeaderBar.vala:75
-msgid "Insert"
-msgstr "തിരുകുക"
-
-#: Layouts/HeaderBar.vala:82
-msgid "Group"
-msgstr "കൂട്ടമാക്കുക"
-
-#: Layouts/HeaderBar.vala:84
-msgid "Ungroup"
-msgstr "കൂട്ടം തെറ്റിക്കുക"
-
-#: Layouts/HeaderBar.vala:87
-msgid "Up"
-msgstr "മേലെ"
-
-#: Layouts/HeaderBar.vala:92
-msgid "Down"
-msgstr "താഴെ"
-
-#: Layouts/HeaderBar.vala:97
-msgid "Top"
-msgstr "മുകളില്"
-
-#: Layouts/HeaderBar.vala:102
-msgid "Bottom"
-msgstr "അടിയില്"
-
-#: Layouts/HeaderBar.vala:107
-msgid "Settings"
-msgstr "സജ്ജീകരണങ്ങള്"
-
-#: Layouts/HeaderBar.vala:118
-msgid "Difference"
-msgstr "വ്യത്യാസം"
-
-#: Layouts/HeaderBar.vala:120
-msgid "Exclusion"
-msgstr "ഒഴിവാക്കിയത്"
-
-#: Layouts/HeaderBar.vala:122
-msgid "Intersect"
-msgstr "നുറുക്കുക"
-
-#: Layouts/HeaderBar.vala:124
-msgid "Union"
-msgstr "ഏകീകരിക്കുക"
-
-#: Layouts/HeaderBar.vala:161
-msgid "New Window"
-msgstr "പുതിയ ജാലകം"
-
-#: Layouts/HeaderBar.vala:182
-msgid "Open Recent"
-msgstr "അടുത്തിടെയുള്ളവ തുറക്കുക"
-
-#: Layouts/HeaderBar.vala:195
-msgid "Save As"
-msgstr "മറ്റൊന്നായി സൂക്ഷിക്കുക"
-
-#: Layouts/HeaderBar.vala:204
-msgid "Quit"
-msgstr "പുറത്ത് കടക്കുക"
-
-#: Layouts/HeaderBar.vala:237
-msgid "Artboard"
-msgstr "കലാഫലകം"
-
-#: Layouts/HeaderBar.vala:254
-msgid "Add Items"
-msgstr "സാധനങ്ങള് ചേര്ക്കുക"
-
-#: Layouts/HeaderBar.vala:262
-msgid "Rectangle"
-msgstr "ചതുരം"
-
-#: Layouts/HeaderBar.vala:268
-msgid "Ellipse"
-msgstr "വട്ടം"
-
-#: Layouts/HeaderBar.vala:286
-msgid "Vector"
-msgstr "ജ്യാമിത്ചിത്രം(വെക്ടര്)"
-
-#: Layouts/HeaderBar.vala:288
-msgid "Pencil"
-msgstr "പെന്സില്"
-
-#: Layouts/HeaderBar.vala:291
-msgid "Text"
-msgstr "എഴുത്ത്"
-
-#: Layouts/HeaderBar.vala:297
-msgid "Image"
-msgstr "ചിത്രം"
-
-#: Layouts/HeaderBar.vala:330
-msgid "Export Current Selection"
-msgstr "തിരഞ്ഞെടുത്തിരിക്കുന്നവ കയറ്റുമതി ചെയ്യുക"
-
-#: Layouts/HeaderBar.vala:336
-msgid "Export Artboards"
-msgstr "കലാഫലകങ്ങള് ഇറക്കുമതി ചെയ്യുക"
-
-#: Layouts/HeaderBar.vala:345
-msgid "Highlight Area to Export"
-msgstr "കയറ്റുമതി ചെയ്യാനുള്ള സ്ഥലം എടുത്തുകാട്ടുക"
-
-#: Layouts/HeaderBar.vala:391
-msgid "Main Menu"
-msgstr "പ്രധാന മെനു"
-
-#: Layouts/HeaderBar.vala:468 Services/ActionManager.vala:224 Services/ActionManager.vala:243
-#: Services/ActionManager.vala:262
-#, c-format
-msgid "Unable to open file at '%s'"
-msgstr "'%s'ലുള്ള രേഖ തുറക്കുവാന് സാധിക്കുന്നില്ല"
-
-#: Layouts/MainCanvas.vala:46
-msgid "Button was pressed!"
-msgstr "ബട്ടണ് അമര്ത്തി!"
-
-#: Layouts/MainCanvas.vala:206
-msgid "Export completed!"
-msgstr "കയറ്റുമതി ചെയ്തു കഴിഞ്ഞു!"
-
-#: Layouts/Partials/AlignItemsPanel.vala:48
-msgid "Distribute Horizontally"
-msgstr "വരിയില് അടുക്കുക"
-
-#: Layouts/Partials/AlignItemsPanel.vala:50
-msgid "Distribute Vertically"
-msgstr "നിരയില് അടുക്കുക"
-
-#: Layouts/Partials/AlignItemsPanel.vala:52
-msgid "Align Left"
-msgstr "ഇടതു ചേര്ക്കുക"
-
-#: Layouts/Partials/AlignItemsPanel.vala:53
-msgid "Align Center"
-msgstr "നടുക്കു വയ്ക്കുക"
-
-#: Layouts/Partials/AlignItemsPanel.vala:54
-msgid "Align Right"
-msgstr "വലതു ചേര്ക്കുക"
-
-#: Layouts/Partials/AlignItemsPanel.vala:56
-msgid "Align Top"
-msgstr "മേലെ ചേര്ത്തു വയ്ക്കുക"
-
-#: Layouts/Partials/AlignItemsPanel.vala:57
-msgid "Align Middle"
-msgstr "ഇടയില് വയ്ക്കുക"
-
-#: Layouts/Partials/AlignItemsPanel.vala:58
-msgid "Align Bottom"
-msgstr "അടിചേര്ക്കുക"
-
-#: Layouts/Partials/Artboard.vala:144 Layouts/Partials/Artboard.vala:487
-#: Layouts/Partials/Layer.vala:139 Layouts/Partials/Layer.vala:687
-msgid "Lock Layer"
-msgstr "പാളി പൂട്ടുക"
-
-#: Layouts/Partials/Artboard.vala:155 Layouts/Partials/Artboard.vala:529
-#: Layouts/Partials/Layer.vala:156 Layouts/Partials/Layer.vala:729
-msgid "Hide Layer"
-msgstr "പാളി ഒളിപ്പിക്കുക"
-
-#: Layouts/Partials/Artboard.vala:487 Layouts/Partials/Layer.vala:687
-msgid "Unlock Layer"
-msgstr "പാളി തുറന്നിടുക"
-
-#: Layouts/Partials/Artboard.vala:529 Layouts/Partials/Layer.vala:729
-msgid "Show Layer"
-msgstr "പാളി കാണിക്കുക"
-
-#: Layouts/Partials/BorderItem.vala:121
-msgid "Choose border color"
-msgstr "അതിര് നിറം തിരഞ്ഞെടുക്കുക"
-
-#: Layouts/Partials/BorderItem.vala:176 Layouts/Partials/FillItem.vala:178
-msgid "Pick color"
-msgstr "നിറം എടുക്കുക"
-
-#: Layouts/Partials/BorderItem.vala:191
-msgid "Remove border"
-msgstr "അതിര് നീക്കം ചെയ്യുക"
-
-#: Layouts/Partials/BorderItem.vala:275
-msgid "Show border"
-msgstr "അതിര് കാണിക്കുക"
-
-#: Layouts/Partials/BorderItem.vala:279
-msgid "Hide border"
-msgstr "അതിര് ഒളിപ്പിക്കുക"
-
-#: Layouts/Partials/BorderRadiusPanel.vala:86
-msgid "Style"
-msgstr "ഭംഗി"
-
-#: Layouts/Partials/BorderRadiusPanel.vala:103
-msgid "Border Radius"
-msgstr "അതിരിന്റെ ആരം"
-
-#: Layouts/Partials/BorderRadiusPanel.vala:137
-msgid "Border radius options"
-msgstr "അതിര് ആരത്തിന്റെ സജ്ജീകരണങ്ങള്"
-
-#: Layouts/Partials/BorderRadiusPanel.vala:199
-msgid "Autoscale Corners"
-msgstr "മൂലകള് താനേ വിസ്തൃതമാക്കുക"
-
-#: Layouts/Partials/BorderRadiusPanel.vala:208
-msgid "Uniform Corners"
-msgstr "മൂലകള് ഏകികരിക്കുക"
-
-#: Layouts/Partials/BordersPanel.vala:53
-msgid "Borders"
-msgstr "അതിരുകള്"
-
-#: Layouts/Partials/BordersPanel.vala:64
-msgid "Add border"
-msgstr "അതിരു ചേര്ക്കുക"
-
-#: Layouts/Partials/FillItem.vala:114
-msgid "Choose fill color"
-msgstr "അകനിറം തിരഞ്ഞെടുക്കുക"
-
-#: Layouts/Partials/FillItem.vala:193
-msgid "Remove fill color"
-msgstr "അകനിറം ഒഴിവാക്കുക"
-
-#: Layouts/Partials/FillItem.vala:277
-msgid "Show fill color"
-msgstr "അകനിറം കാണിക്കുക"
-
-#: Layouts/Partials/FillItem.vala:281
-msgid "Hide fill color"
-msgstr "അകനിറം ഒളിപ്പിക്കുക"
-
-#: Layouts/Partials/FillsPanel.vala:54
-msgid "Fills"
-msgstr "അകനിറങ്ങള്"
-
-#: Layouts/Partials/FillsPanel.vala:65
-msgid "Add fill color"
-msgstr "അകനിറം ചേര്ക്കുക"
-
-#: Layouts/Partials/TransformPanel.vala:96
-msgid "X"
-msgstr "X"
-
-#: Layouts/Partials/TransformPanel.vala:96
-msgid "Horizontal position"
-msgstr "വിലങ്ങനെയുള്ള സ്ഥാനം"
-
-#: Layouts/Partials/TransformPanel.vala:98
-msgid "Y"
-msgstr "Y"
-
-#: Layouts/Partials/TransformPanel.vala:98
-msgid "Vertical position"
-msgstr "കുത്തനെയുള്ള സ്ഥാനം"
-
-#: Layouts/Partials/TransformPanel.vala:100
-msgid "W"
-msgstr "W"
-
-#: Layouts/Partials/TransformPanel.vala:100
-msgid "Width"
-msgstr "വീതി"
-
-#: Layouts/Partials/TransformPanel.vala:102
-msgid "H"
-msgstr "H"
-
-#: Layouts/Partials/TransformPanel.vala:102
-msgid "Height"
-msgstr "ഉയരം"
-
-#: Layouts/Partials/TransformPanel.vala:107
-msgid "Lock Ratio"
-msgstr "സ്ഥിര അംശബന്ധം"
-
-#: Layouts/Partials/TransformPanel.vala:114
-msgid "R"
-msgstr "R"
-
-#: Layouts/Partials/TransformPanel.vala:114
-msgid "Rotation degrees"
-msgstr "കറക്കം ഡിഗ്രിയില്"
-
-#: Layouts/Partials/TransformPanel.vala:126
-msgid "Flip Horizontally"
-msgstr "വിലങ്ങനെ മറിക്കുക"
-
-#: Layouts/Partials/TransformPanel.vala:137
-msgid "Flip Vertically"
-msgstr "കുത്തനെ മറിക്കുക"
-
-#: Layouts/Partials/TransformPanel.vala:165
-msgid "Position"
-msgstr "സ്ഥാനം"
-
-#: Layouts/Partials/TransformPanel.vala:169
-msgid "Size"
-msgstr "വലുപ്പം"
-
-#: Layouts/Partials/TransformPanel.vala:178
-msgid "Opacity"
-msgstr "സുതാര്യത"
-
-#: Layouts/RightSideBar.vala:111
-msgid "Search Layer"
-msgstr "പാളി പരതുക"
-
-#: Lib/Managers/ExportManager.vala:192 Lib/Managers/ExportManager.vala:219
-msgid "Generating preview, please wait…"
-msgstr "പൂര്വ്വദൃശ്യം രുപികരിക്കുന്നു, ദയവായി കാക്കുക…"
-
-#: Lib/Managers/ExportManager.vala:313
-#, c-format
-msgid "Untitled %i"
-msgstr "പേരില്ലാത്തത് %i"
-
-#: Lib/Managers/ExportManager.vala:484
-msgid "Exporting images…"
-msgstr "ചിത്രങ്ങള് കയറ്റുമതി ചെയ്യുന്നു…"
-
-#: Partials/ExportWidget.vala:117
-#, c-format
-msgid "%i × %i px · %s"
-msgstr "%i × %i px · %s"
-
-#: Partials/ExportWidget.vala:124
-msgid "Fetching image size…"
-msgstr "ചിത്രവലുപ്പം കണ്ടെത്തുന്നു…"
-
-#: Partials/ZoomButton.vala:49
-msgid "Zoom Out"
-msgstr "ചെറുതാക്കിക്കാണിക്കുക"
-
-#: Partials/ZoomButton.vala:55
-msgid "Reset Zoom"
-msgstr "പഴയ വലുപ്പത്തിലാക്കുക"
-
-#: Partials/ZoomButton.vala:62
-msgid "Zoom In"
-msgstr "വലുതാക്കിക്കാണിക്കുക"
-
-#: Partials/ZoomButton.vala:68
-msgid "Zoom"
-msgstr "വലുപ്പം ക്രമീകരിക്കുക"
-
-#: Services/ActionManager.vala:217
-msgid "No recently opened file available!"
-msgstr "അവസാനം തുറന്ന ഒരു രേഖയും കിട്ടാനില്ല!"
-
-#: Services/ActionManager.vala:236
-msgid "No second most recently opened file available!"
-msgstr "അവസാനം രണ്ടാമതായി തുറന്ന ഒരു രേഖയും കിട്ടാനില്ല!"
-
-#: Services/ActionManager.vala:255
-msgid "No third most recently opened file available!"
-msgstr "അവസാനം മൂന്നാമതായി തുറന്ന ഒരു രേഖയും കിട്ടാനില്ല!"
-
-#: Services/ActionManager.vala:293
-msgid "Nothing selected to export!"
-msgstr "കയറ്റുമതി ചെയ്യാന് ഒന്നും തിരഞ്ഞെടുത്തിട്ടില്ല!"
-
-#: Services/ActionManager.vala:302
-msgid "Export of Artboards currently unavailable…sorry 😑️"
-msgstr "ക്ഷമിക്കണം…കലാഫലകങ്ങളുടെ കയറ്റുമതി ഇപ്പോള് സാധ്യമല്ല 😑️"
-
-#: Services/ActionManager.vala:373
-msgid "Choose image file"
-msgstr "ചിത്രരേഖ തുറക്കുക"
-
-#: Services/ActionManager.vala:373
-msgid "Select"
-msgstr "തിരഞ്ഞെടുക്കുക"
-
-#: Services/ActionManager.vala:373
-msgid "Close"
-msgstr "അടക്കുക"
-
-#: Services/ActionManager.vala:442
-#, c-format
-msgid "Error! .%s files are not supported!"
-msgstr "പ്രശ്നമായി! .%s രേഖകള് പിന്തുണക്കപ്പെടുന്നവയല്ല!"
-
-#: Window.vala:121
-msgid "Are you sure you want to quit?"
-msgstr "പുറത്തിറങ്ങുകയാണെന്നുറപ്പാണോ?"
-
-#: Window.vala:122
-msgid "All unsaved data will be lost and impossible to recover."
-msgstr "സൂക്ഷിക്കാത്ത എല്ലാ വിവരങ്ങളും തിരിച്ചെടുക്കാനാകാത്തവിധത്തില് നഷ്ടപ്പെടും."
-
-#: Window.vala:124
-msgid "Quit without saving!"
-msgstr "സൂക്ഷിക്കാതെ പുറത്തുറങ്ങുക!"
-
-#: Window.vala:125
-msgid "Save file"
-msgstr "രേഖ സൂക്ഷിക്കുക"
diff --git a/po/mn.po b/po/mn.po
deleted file mode 100644
index 7d7bf5d53..000000000
--- a/po/mn.po
+++ /dev/null
@@ -1,4 +0,0 @@
-msgid ""
-msgstr ""
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
diff --git a/po/mo.po b/po/mo.po
deleted file mode 100644
index 7d7bf5d53..000000000
--- a/po/mo.po
+++ /dev/null
@@ -1,4 +0,0 @@
-msgid ""
-msgstr ""
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
diff --git a/po/mr.po b/po/mr.po
deleted file mode 100644
index 7d7bf5d53..000000000
--- a/po/mr.po
+++ /dev/null
@@ -1,4 +0,0 @@
-msgid ""
-msgstr ""
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
diff --git a/po/ms.po b/po/ms.po
deleted file mode 100644
index 7d7bf5d53..000000000
--- a/po/ms.po
+++ /dev/null
@@ -1,4 +0,0 @@
-msgid ""
-msgstr ""
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
diff --git a/po/mt.po b/po/mt.po
deleted file mode 100644
index 7d7bf5d53..000000000
--- a/po/mt.po
+++ /dev/null
@@ -1,4 +0,0 @@
-msgid ""
-msgstr ""
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
diff --git a/po/my.po b/po/my.po
deleted file mode 100644
index 7d7bf5d53..000000000
--- a/po/my.po
+++ /dev/null
@@ -1,4 +0,0 @@
-msgid ""
-msgstr ""
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
diff --git a/po/na.po b/po/na.po
deleted file mode 100644
index 7d7bf5d53..000000000
--- a/po/na.po
+++ /dev/null
@@ -1,4 +0,0 @@
-msgid ""
-msgstr ""
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
diff --git a/po/nb.po b/po/nb.po
deleted file mode 100644
index ca301d2fd..000000000
--- a/po/nb.po
+++ /dev/null
@@ -1,5 +0,0 @@
-msgid ""
-msgstr ""
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
-"Plural-Forms: nplurals=2; plural=n != 1;\n"
diff --git a/po/nd.po b/po/nd.po
deleted file mode 100644
index 7d7bf5d53..000000000
--- a/po/nd.po
+++ /dev/null
@@ -1,4 +0,0 @@
-msgid ""
-msgstr ""
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
diff --git a/po/ne.po b/po/ne.po
deleted file mode 100644
index 7d7bf5d53..000000000
--- a/po/ne.po
+++ /dev/null
@@ -1,4 +0,0 @@
-msgid ""
-msgstr ""
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
diff --git a/po/ng.po b/po/ng.po
deleted file mode 100644
index 7d7bf5d53..000000000
--- a/po/ng.po
+++ /dev/null
@@ -1,4 +0,0 @@
-msgid ""
-msgstr ""
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
diff --git a/po/nl.po b/po/nl.po
deleted file mode 100644
index 1802a9dc8..000000000
--- a/po/nl.po
+++ /dev/null
@@ -1,711 +0,0 @@
-msgid ""
-msgstr ""
-"Project-Id-Version: \n"
-"POT-Creation-Date: 2020-09-03 18:20+0200\n"
-"PO-Revision-Date: \n"
-"Last-Translator: Heimen Stoffels \n"
-"Language-Team: \n"
-"Language: nl\n"
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
-"Content-Transfer-Encoding: 8bit\n"
-"Plural-Forms: nplurals=2; plural=n != 1;\n"
-"X-Generator: Poedit 2.4.1\n"
-"X-Poedit-Basepath: ../src\n"
-"X-Poedit-SearchPath-0: .\n"
-
-#: Dialogs/ExportDialog.vala:151
-msgid "Export to:"
-msgstr "Exporteren naar:"
-
-#: Dialogs/ExportDialog.vala:157
-msgid "Select Folder"
-msgstr "Kies een map"
-
-#: Dialogs/ExportDialog.vala:166
-msgid "Format:"
-msgstr "Formaat:"
-
-#: Dialogs/ExportDialog.vala:179
-msgid "Quality:"
-msgstr "Kwaliteit:"
-
-#: Dialogs/ExportDialog.vala:191
-msgid "Compression:"
-msgstr "Compressie:"
-
-#: Dialogs/ExportDialog.vala:205
-msgid "Transparency:"
-msgstr "Doorzichtigheid:"
-
-#: Dialogs/ExportDialog.vala:218
-msgid "Scale:"
-msgstr "Schaal:"
-
-#: Dialogs/ExportDialog.vala:242 FileFormat/FileManager.vala:49
-#: FileFormat/FileManager.vala:105
-msgid "Cancel"
-msgstr "Annuleren"
-
-#: Dialogs/ExportDialog.vala:249 Dialogs/ShortcutsDialog.vala:63
-#: Layouts/HeaderBar.vala:112
-msgid "Export"
-msgstr "Exporteren"
-
-#: Dialogs/ReleaseDialog.vala:47 Dialogs/SettingsDialog.vala:217
-msgid ""
-"WARNING!\n"
-"Akira is still under development and not ready for production. Missing "
-"features, random bugs, and black holes opening in your kitchen are to be "
-"expected."
-msgstr ""
-
-#: Dialogs/ReleaseDialog.vala:100 Dialogs/SettingsDialog.vala:249
-msgid "Make a Donation"
-msgstr "Doneren"
-
-#: Dialogs/ReleaseDialog.vala:109 Dialogs/SettingsDialog.vala:258
-msgid "Suggest Translations"
-msgstr "Vertalen"
-
-#: Dialogs/ReleaseDialog.vala:118 Dialogs/SettingsDialog.vala:267
-msgid "Report a Problem"
-msgstr "Probleem melden"
-
-#: Dialogs/SettingsDialog.vala:40
-msgid "Preferences"
-msgstr "Voorkeuren"
-
-#: Dialogs/SettingsDialog.vala:50 Dialogs/SettingsDialog.vala:73
-#: Dialogs/ShortcutsDialog.vala:45
-msgid "General"
-msgstr "Algemeen"
-
-#: Dialogs/SettingsDialog.vala:51 Dialogs/SettingsDialog.vala:86
-msgid "Interface"
-msgstr "Uiterlijk"
-
-#: Dialogs/SettingsDialog.vala:52 Layouts/HeaderBar.vala:280
-msgid "Shapes"
-msgstr "Vormen"
-
-#: Dialogs/SettingsDialog.vala:53
-msgid "About"
-msgstr "Over"
-
-#: Dialogs/SettingsDialog.vala:74
-msgid "Auto Reopen Latest File:"
-msgstr "Recentste bestand automatisch openen:"
-
-#: Dialogs/SettingsDialog.vala:88
-msgid "Use Dark Theme:"
-msgstr "Donker thema gebruiken:"
-
-#: Dialogs/SettingsDialog.vala:92
-msgid "Invert Panels Order:"
-msgstr "Paneelvolgorde omkeren:"
-
-#: Dialogs/SettingsDialog.vala:96
-msgid "Restart application to apply this change."
-msgstr "Herstart de toepassing om de wijzigingen toe te passen."
-
-#: Dialogs/SettingsDialog.vala:100
-msgid "ToolBar Style"
-msgstr "Werkbalkstijl"
-
-#: Dialogs/SettingsDialog.vala:102
-msgid "Show Button Labels:"
-msgstr "Knopteksten tonen:"
-
-#: Dialogs/SettingsDialog.vala:106
-msgid "Use Symbolic Icons:"
-msgstr "Symbolische pictogrammen gebruiken:"
-
-#: Dialogs/SettingsDialog.vala:129
-msgid "Default Colors"
-msgstr "Standaardkleuren"
-
-#: Dialogs/SettingsDialog.vala:131
-msgid "Define the default style used when creating a new shape."
-msgstr ""
-"Geef op welke stijl moet worden gebruikt bij het maken van een nieuwe "
-"vorm."
-
-#: Dialogs/SettingsDialog.vala:136
-msgid "Fill Color:"
-msgstr "Opvulkleur:"
-
-#: Dialogs/SettingsDialog.vala:157
-msgid "Enable Border Style:"
-msgstr "Randstijl gebruiken:"
-
-#: Dialogs/SettingsDialog.vala:160
-msgid "Border Color:"
-msgstr "Randkleur:"
-
-#: Dialogs/SettingsDialog.vala:181
-msgid "Border Width:"
-msgstr "Randbreedte:"
-
-#: Dialogs/SettingsDialog.vala:209
-msgid "The Linux Design Tool"
-msgstr "Hét Linux-ontwerpprogramma"
-
-#: Dialogs/SettingsDialog.vala:226
-msgid "Thanks to our awesome supporters!"
-msgstr "Met dank aan onze geweldige ondersteuners!"
-
-#: Dialogs/SettingsDialog.vala:231
-msgid "View the list of supporters"
-msgstr "Ondersteunerlijst bekijken"
-
-#: Dialogs/ShortcutsDialog.vala:46
-msgid "New window:"
-msgstr "Nieuw venster:"
-
-#: Dialogs/ShortcutsDialog.vala:48
-msgid "Preferences:"
-msgstr "Voorkeuren:"
-
-#: Dialogs/ShortcutsDialog.vala:50
-msgid "Quit:"
-msgstr "Afsluiten:"
-
-#: Dialogs/ShortcutsDialog.vala:52
-msgid "Presentation mode:"
-msgstr "Presentatiemodus:"
-
-#: Dialogs/ShortcutsDialog.vala:55
-msgid "File"
-msgstr "Bestand"
-
-#: Dialogs/ShortcutsDialog.vala:56
-msgid "Open:"
-msgstr "Openen:"
-
-#: Dialogs/ShortcutsDialog.vala:58
-msgid "Save:"
-msgstr "Opslaan:"
-
-#: Dialogs/ShortcutsDialog.vala:60
-msgid "Save as:"
-msgstr "Opslaan als:"
-
-#: Dialogs/ShortcutsDialog.vala:64
-msgid "Export artboards:"
-msgstr "Ontwerpborden exporteren:"
-
-#: Dialogs/ShortcutsDialog.vala:66
-msgid "Export selection:"
-msgstr "Selectie exporteren:"
-
-#: Dialogs/ShortcutsDialog.vala:68
-msgid "Highlight area to export:"
-msgstr "Markeer het te exporteren gebied:"
-
-#: Dialogs/ShortcutsDialog.vala:77
-msgid "Canvas"
-msgstr "Canvas"
-
-#: Dialogs/ShortcutsDialog.vala:78
-msgid "Zoom in:"
-msgstr "Inzoomen:"
-
-#: Dialogs/ShortcutsDialog.vala:80
-msgid "Zoom out:"
-msgstr "Uitzoomen:"
-
-#: Dialogs/ShortcutsDialog.vala:82
-msgid "Zoom reset:"
-msgstr "Standaard zoomniveau:"
-
-#: Dialogs/ShortcutsDialog.vala:85
-msgid "Item creation"
-msgstr "Items maken"
-
-#: Dialogs/ShortcutsDialog.vala:86
-msgid "Artboard:"
-msgstr "Ontwerpbord:"
-
-#: Dialogs/ShortcutsDialog.vala:88
-msgid "Rectangle:"
-msgstr "Rechthoek:"
-
-#: Dialogs/ShortcutsDialog.vala:90
-msgid "Ellipse:"
-msgstr "Ellips:"
-
-#: Dialogs/ShortcutsDialog.vala:92
-msgid "Text:"
-msgstr "Tekst:"
-
-#: Dialogs/ShortcutsDialog.vala:94
-msgid "Image:"
-msgstr "Afbeelding:"
-
-#: Dialogs/ShortcutsDialog.vala:97 Layouts/Partials/TransformPanel.vala:174
-msgid "Transform"
-msgstr "Transformeren"
-
-#: Dialogs/ShortcutsDialog.vala:98
-msgid "Raise selection:"
-msgstr "Selectie verhogen:"
-
-#: Dialogs/ShortcutsDialog.vala:100
-msgid "Lower selection:"
-msgstr "Selectie verlagen:"
-
-#: Dialogs/ShortcutsDialog.vala:102
-msgid "Raise selection to top:"
-msgstr "Selectie naar bovenkant:"
-
-#: Dialogs/ShortcutsDialog.vala:104
-msgid "Lower selection to bottom:"
-msgstr "Selectie naar onderkant:"
-
-#: Dialogs/ShortcutsDialog.vala:106
-msgid "Flip horizontally:"
-msgstr "Horizontaal spiegelen:"
-
-#: Dialogs/ShortcutsDialog.vala:108
-msgid "Flip vertically:"
-msgstr "Verticaal spiegelen:"
-
-#: FileFormat/FileManager.vala:46
-msgid "Save Akira file"
-msgstr "Akira-bestand opslaan"
-
-#: FileFormat/FileManager.vala:48 Layouts/HeaderBar.vala:190
-msgid "Save"
-msgstr "Opslaan"
-
-#: FileFormat/FileManager.vala:71
-msgid "Akira files"
-msgstr "Akira-bestanden"
-
-#: FileFormat/FileManager.vala:76
-msgid "All files"
-msgstr "Alle bestanden"
-
-#: FileFormat/FileManager.vala:103
-msgid "Open Akira file"
-msgstr "Akira-bestand openen"
-
-#: FileFormat/FileManager.vala:105 Layouts/HeaderBar.vala:170
-msgid "Open"
-msgstr "Openen"
-
-#: Layouts/HeaderBar.vala:69 Lib/Managers/ExportManager.vala:296
-msgid "Untitled"
-msgstr "Naamloos"
-
-#: Layouts/HeaderBar.vala:71
-msgid "Menu"
-msgstr "Menu"
-
-#: Layouts/HeaderBar.vala:75
-msgid "Insert"
-msgstr "Invoegen"
-
-#: Layouts/HeaderBar.vala:82
-msgid "Group"
-msgstr "Groeperen"
-
-#: Layouts/HeaderBar.vala:84
-msgid "Ungroup"
-msgstr "Degroeperen"
-
-#: Layouts/HeaderBar.vala:87
-msgid "Up"
-msgstr "Omhoog"
-
-#: Layouts/HeaderBar.vala:92
-msgid "Down"
-msgstr "Omlaag"
-
-#: Layouts/HeaderBar.vala:97
-msgid "Top"
-msgstr "Bovenkant"
-
-#: Layouts/HeaderBar.vala:102
-msgid "Bottom"
-msgstr "Onderkant"
-
-#: Layouts/HeaderBar.vala:107
-msgid "Settings"
-msgstr "Instellingen"
-
-#: Layouts/HeaderBar.vala:118
-msgid "Difference"
-msgstr "Verschil"
-
-#: Layouts/HeaderBar.vala:120
-msgid "Exclusion"
-msgstr "Uitsluiten"
-
-#: Layouts/HeaderBar.vala:122
-msgid "Intersect"
-msgstr "Kruisen"
-
-#: Layouts/HeaderBar.vala:124
-msgid "Union"
-msgstr "Verenigen"
-
-#: Layouts/HeaderBar.vala:161
-msgid "New Window"
-msgstr "Nieuw venster"
-
-#: Layouts/HeaderBar.vala:182
-msgid "Open Recent"
-msgstr "Recent bestand openen"
-
-#: Layouts/HeaderBar.vala:195
-msgid "Save As"
-msgstr "Opslaan als"
-
-#: Layouts/HeaderBar.vala:204
-msgid "Quit"
-msgstr "Afsluiten"
-
-#: Layouts/HeaderBar.vala:237
-msgid "Artboard"
-msgstr "Ontwerpbord"
-
-#: Layouts/HeaderBar.vala:254
-msgid "Add Items"
-msgstr "Items toevoegen"
-
-#: Layouts/HeaderBar.vala:262
-msgid "Rectangle"
-msgstr "Rechthoek"
-
-#: Layouts/HeaderBar.vala:268
-msgid "Ellipse"
-msgstr "Ellips"
-
-#: Layouts/HeaderBar.vala:286
-msgid "Vector"
-msgstr "Vector"
-
-#: Layouts/HeaderBar.vala:288
-msgid "Pencil"
-msgstr "Potlood"
-
-#: Layouts/HeaderBar.vala:291
-msgid "Text"
-msgstr "Tekst"
-
-#: Layouts/HeaderBar.vala:297
-msgid "Image"
-msgstr "Afbeelding"
-
-#: Layouts/HeaderBar.vala:330
-msgid "Export Current Selection"
-msgstr "Huidige selectie exporteren"
-
-#: Layouts/HeaderBar.vala:336
-msgid "Export Artboards"
-msgstr "Ontwerpborden exporteren"
-
-#: Layouts/HeaderBar.vala:345
-msgid "Highlight Area to Export"
-msgstr "Markeer het te exporteren gebied"
-
-#: Layouts/HeaderBar.vala:391
-msgid "Main Menu"
-msgstr "Hoofdmenu"
-
-#: Layouts/HeaderBar.vala:468 Services/ActionManager.vala:224
-#: Services/ActionManager.vala:243 Services/ActionManager.vala:262
-#, c-format
-msgid "Unable to open file at '%s'"
-msgstr "Het bestand in '%s' kan niet worden geopend"
-
-#: Layouts/MainCanvas.vala:46
-msgid "Button was pressed!"
-msgstr "De knop is ingedrukt!"
-
-#: Layouts/MainCanvas.vala:206
-msgid "Export completed!"
-msgstr "Exporteren voltooid!"
-
-#: Layouts/Partials/AlignItemsPanel.vala:48
-msgid "Distribute Horizontally"
-msgstr "Horizontaal opdelen"
-
-#: Layouts/Partials/AlignItemsPanel.vala:50
-msgid "Distribute Vertically"
-msgstr "Verticaal opdelen"
-
-#: Layouts/Partials/AlignItemsPanel.vala:52
-msgid "Align Left"
-msgstr "Links uitlijnen"
-
-#: Layouts/Partials/AlignItemsPanel.vala:53
-msgid "Align Center"
-msgstr "Centreren"
-
-#: Layouts/Partials/AlignItemsPanel.vala:54
-msgid "Align Right"
-msgstr "Rechts uitlijnen"
-
-#: Layouts/Partials/AlignItemsPanel.vala:56
-msgid "Align Top"
-msgstr "Aan bovenkant uitlijnen"
-
-#: Layouts/Partials/AlignItemsPanel.vala:57
-msgid "Align Middle"
-msgstr "Gecentreerd uitlijnen"
-
-#: Layouts/Partials/AlignItemsPanel.vala:58
-msgid "Align Bottom"
-msgstr "Aan onderkant uitlijnen"
-
-#: Layouts/Partials/Artboard.vala:144 Layouts/Partials/Artboard.vala:487
-#: Layouts/Partials/Layer.vala:139 Layouts/Partials/Layer.vala:687
-msgid "Lock Layer"
-msgstr "Laag vergrendelen"
-
-#: Layouts/Partials/Artboard.vala:155 Layouts/Partials/Artboard.vala:529
-#: Layouts/Partials/Layer.vala:156 Layouts/Partials/Layer.vala:729
-msgid "Hide Layer"
-msgstr "Laag verbergen"
-
-#: Layouts/Partials/Artboard.vala:487 Layouts/Partials/Layer.vala:687
-msgid "Unlock Layer"
-msgstr "Laag ontgrendelen"
-
-#: Layouts/Partials/Artboard.vala:529 Layouts/Partials/Layer.vala:729
-msgid "Show Layer"
-msgstr "Laag tonen"
-
-#: Layouts/Partials/BorderItem.vala:121
-msgid "Choose border color"
-msgstr "Kies een randkleur"
-
-#: Layouts/Partials/BorderItem.vala:176 Layouts/Partials/FillItem.vala:178
-msgid "Pick color"
-msgstr "Kleur kiezen"
-
-#: Layouts/Partials/BorderItem.vala:191
-msgid "Remove border"
-msgstr "Rand verwijderen"
-
-#: Layouts/Partials/BorderItem.vala:275
-msgid "Show border"
-msgstr "Rand tonen"
-
-#: Layouts/Partials/BorderItem.vala:279
-msgid "Hide border"
-msgstr "Rand verbergen"
-
-#: Layouts/Partials/BorderRadiusPanel.vala:86
-msgid "Style"
-msgstr "Stijl"
-
-#: Layouts/Partials/BorderRadiusPanel.vala:103
-msgid "Border Radius"
-msgstr "Randstraal"
-
-#: Layouts/Partials/BorderRadiusPanel.vala:137
-msgid "Border radius options"
-msgstr "Randstraalopties"
-
-#: Layouts/Partials/BorderRadiusPanel.vala:199
-msgid "Autoscale Corners"
-msgstr "Hoeken automatisch schalen"
-
-#: Layouts/Partials/BorderRadiusPanel.vala:208
-msgid "Uniform Corners"
-msgstr "Hoeken verenigen"
-
-#: Layouts/Partials/BordersPanel.vala:53
-msgid "Borders"
-msgstr "Randen"
-
-#: Layouts/Partials/BordersPanel.vala:64
-msgid "Add border"
-msgstr "Rand toevoegen"
-
-#: Layouts/Partials/FillItem.vala:114
-msgid "Choose fill color"
-msgstr "Kies een opvulkleur"
-
-#: Layouts/Partials/FillItem.vala:193
-msgid "Remove fill color"
-msgstr "Opvulkleur verwijderen"
-
-#: Layouts/Partials/FillItem.vala:277
-msgid "Show fill color"
-msgstr "Opvulkleur tonen"
-
-#: Layouts/Partials/FillItem.vala:281
-msgid "Hide fill color"
-msgstr "Opvulkleur verbergen"
-
-#: Layouts/Partials/FillsPanel.vala:54
-msgid "Fills"
-msgstr "Opvullen"
-
-#: Layouts/Partials/FillsPanel.vala:65
-msgid "Add fill color"
-msgstr "Opvulkleur toevoegen"
-
-#: Layouts/Partials/TransformPanel.vala:96
-msgid "X"
-msgstr "X"
-
-#: Layouts/Partials/TransformPanel.vala:96
-msgid "Horizontal position"
-msgstr "Horizontale positie"
-
-#: Layouts/Partials/TransformPanel.vala:98
-msgid "Y"
-msgstr "Y"
-
-#: Layouts/Partials/TransformPanel.vala:98
-msgid "Vertical position"
-msgstr "Verticale positie"
-
-#: Layouts/Partials/TransformPanel.vala:100
-msgid "W"
-msgstr "W"
-
-#: Layouts/Partials/TransformPanel.vala:100
-msgid "Width"
-msgstr "Breedte"
-
-#: Layouts/Partials/TransformPanel.vala:102
-msgid "H"
-msgstr "H"
-
-#: Layouts/Partials/TransformPanel.vala:102
-msgid "Height"
-msgstr "Hoogte"
-
-#: Layouts/Partials/TransformPanel.vala:107
-msgid "Lock Ratio"
-msgstr "Verhouding vergrendelen"
-
-#: Layouts/Partials/TransformPanel.vala:114
-msgid "R"
-msgstr "R"
-
-#: Layouts/Partials/TransformPanel.vala:114
-msgid "Rotation degrees"
-msgstr "Aantal graden draaien"
-
-#: Layouts/Partials/TransformPanel.vala:126
-msgid "Flip Horizontally"
-msgstr "Horizontaal spiegelen"
-
-#: Layouts/Partials/TransformPanel.vala:137
-msgid "Flip Vertically"
-msgstr "Verticaal spiegelen"
-
-#: Layouts/Partials/TransformPanel.vala:165
-msgid "Position"
-msgstr "Positie"
-
-#: Layouts/Partials/TransformPanel.vala:169
-msgid "Size"
-msgstr "Grootte"
-
-#: Layouts/Partials/TransformPanel.vala:178
-msgid "Opacity"
-msgstr "Doorzichtigheid"
-
-#: Layouts/RightSideBar.vala:111
-msgid "Search Layer"
-msgstr "Laag zoeken"
-
-#: Lib/Managers/ExportManager.vala:192 Lib/Managers/ExportManager.vala:219
-msgid "Generating preview, please wait…"
-msgstr "Bezig met samenstellen van voorvertoning…"
-
-#: Lib/Managers/ExportManager.vala:313
-#, c-format
-msgid "Untitled %i"
-msgstr "Naamloos %i"
-
-#: Lib/Managers/ExportManager.vala:484
-msgid "Exporting images…"
-msgstr "Bezig met exporteren…"
-
-#: Partials/ExportWidget.vala:117
-#, c-format
-msgid "%i × %i px · %s"
-msgstr "%i × %i px · %s"
-
-#: Partials/ExportWidget.vala:124
-msgid "Fetching image size…"
-msgstr "Bezig met ophalen van afbeeldingsgrootte…"
-
-#: Partials/ZoomButton.vala:49
-msgid "Zoom Out"
-msgstr "Uitzoomen"
-
-#: Partials/ZoomButton.vala:55
-msgid "Reset Zoom"
-msgstr "Standaard zoomniveau"
-
-#: Partials/ZoomButton.vala:62
-msgid "Zoom In"
-msgstr "Inzoomen"
-
-#: Partials/ZoomButton.vala:68
-msgid "Zoom"
-msgstr "Zoom"
-
-#: Services/ActionManager.vala:217
-msgid "No recently opened file available!"
-msgstr "Er is geen onlangs geopend bestand!"
-
-#: Services/ActionManager.vala:236
-msgid "No second most recently opened file available!"
-msgstr "Er is geen tweede onlangs geopend bestand!"
-
-#: Services/ActionManager.vala:255
-msgid "No third most recently opened file available!"
-msgstr "Er is geen derde onlangs geopend bestand!"
-
-#: Services/ActionManager.vala:293
-msgid "Nothing selected to export!"
-msgstr "Niets geselecteerd om te exporteren!"
-
-#: Services/ActionManager.vala:302
-msgid "Export of Artboards currently unavailable…sorry 😑️"
-msgstr "Ontwerpborden kunnen momenteel niet worden geëxporteerd… 😑️"
-
-#: Services/ActionManager.vala:373
-msgid "Choose image file"
-msgstr "Kies een afbeelding"
-
-#: Services/ActionManager.vala:373
-msgid "Select"
-msgstr "Kiezen"
-
-#: Services/ActionManager.vala:373
-msgid "Close"
-msgstr "Sluiten"
-
-#: Services/ActionManager.vala:442
-#, c-format
-msgid "Error! .%s files are not supported!"
-msgstr "Fout: .%s-bestanden worden niet ondersteund!"
-
-#: Window.vala:121
-msgid "Are you sure you want to quit?"
-msgstr "Weet je zeker dat je wilt afsluiten?"
-
-#: Window.vala:122
-msgid "All unsaved data will be lost and impossible to recover."
-msgstr "Alle niet-opgeslagen gegevens gaan permanent verloren."
-
-#: Window.vala:124
-msgid "Quit without saving!"
-msgstr "Sluiten zonder opslaan"
-
-#: Window.vala:125
-msgid "Save file"
-msgstr "Bestand opslaan"
diff --git a/po/nn.po b/po/nn.po
deleted file mode 100644
index ca301d2fd..000000000
--- a/po/nn.po
+++ /dev/null
@@ -1,5 +0,0 @@
-msgid ""
-msgstr ""
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
-"Plural-Forms: nplurals=2; plural=n != 1;\n"
diff --git a/po/no.po b/po/no.po
deleted file mode 100644
index ca301d2fd..000000000
--- a/po/no.po
+++ /dev/null
@@ -1,5 +0,0 @@
-msgid ""
-msgstr ""
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
-"Plural-Forms: nplurals=2; plural=n != 1;\n"
diff --git a/po/nr.po b/po/nr.po
deleted file mode 100644
index 7d7bf5d53..000000000
--- a/po/nr.po
+++ /dev/null
@@ -1,4 +0,0 @@
-msgid ""
-msgstr ""
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
diff --git a/po/nv.po b/po/nv.po
deleted file mode 100644
index 7d7bf5d53..000000000
--- a/po/nv.po
+++ /dev/null
@@ -1,4 +0,0 @@
-msgid ""
-msgstr ""
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
diff --git a/po/ny.po b/po/ny.po
deleted file mode 100644
index 7d7bf5d53..000000000
--- a/po/ny.po
+++ /dev/null
@@ -1,4 +0,0 @@
-msgid ""
-msgstr ""
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
diff --git a/po/oc.po b/po/oc.po
deleted file mode 100644
index 7d7bf5d53..000000000
--- a/po/oc.po
+++ /dev/null
@@ -1,4 +0,0 @@
-msgid ""
-msgstr ""
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
diff --git a/po/oj.po b/po/oj.po
deleted file mode 100644
index 7d7bf5d53..000000000
--- a/po/oj.po
+++ /dev/null
@@ -1,4 +0,0 @@
-msgid ""
-msgstr ""
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
diff --git a/po/om.po b/po/om.po
deleted file mode 100644
index 7d7bf5d53..000000000
--- a/po/om.po
+++ /dev/null
@@ -1,4 +0,0 @@
-msgid ""
-msgstr ""
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
diff --git a/po/or.po b/po/or.po
deleted file mode 100644
index 7d7bf5d53..000000000
--- a/po/or.po
+++ /dev/null
@@ -1,4 +0,0 @@
-msgid ""
-msgstr ""
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
diff --git a/po/os.po b/po/os.po
deleted file mode 100644
index 7d7bf5d53..000000000
--- a/po/os.po
+++ /dev/null
@@ -1,4 +0,0 @@
-msgid ""
-msgstr ""
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
diff --git a/po/pa.po b/po/pa.po
deleted file mode 100644
index 7d7bf5d53..000000000
--- a/po/pa.po
+++ /dev/null
@@ -1,4 +0,0 @@
-msgid ""
-msgstr ""
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
diff --git a/po/pi.po b/po/pi.po
deleted file mode 100644
index 7d7bf5d53..000000000
--- a/po/pi.po
+++ /dev/null
@@ -1,4 +0,0 @@
-msgid ""
-msgstr ""
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
diff --git a/po/pl.po b/po/pl.po
deleted file mode 100644
index 24392d3a0..000000000
--- a/po/pl.po
+++ /dev/null
@@ -1,5 +0,0 @@
-msgid ""
-msgstr ""
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
-"Plural-Forms: nplurals=3; plural=n==1 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n"
diff --git a/po/ps.po b/po/ps.po
deleted file mode 100644
index 7d7bf5d53..000000000
--- a/po/ps.po
+++ /dev/null
@@ -1,4 +0,0 @@
-msgid ""
-msgstr ""
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
diff --git a/po/pt.po b/po/pt.po
deleted file mode 100644
index ca301d2fd..000000000
--- a/po/pt.po
+++ /dev/null
@@ -1,5 +0,0 @@
-msgid ""
-msgstr ""
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
-"Plural-Forms: nplurals=2; plural=n != 1;\n"
diff --git a/po/pt_BR.po b/po/pt_BR.po
deleted file mode 100644
index b7d531f2c..000000000
--- a/po/pt_BR.po
+++ /dev/null
@@ -1,664 +0,0 @@
-msgid ""
-msgstr ""
-"Language: pt_BR\n"
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
-"Plural-Forms: nplurals=2; plural=(n > 1);\n"
-"Project-Id-Version: \n"
-"POT-Creation-Date: \n"
-"PO-Revision-Date: \n"
-"Last-Translator: codedracula <62944284+codedracula4ec@users.noreply."
-"github.com>\n"
-"Language-Team: \n"
-"Content-Transfer-Encoding: 8bit\n"
-"X-Generator: Poedit 2.4.1\n"
-
-#: Dialogs/ExportDialog.vala:151
-msgid "Export to:"
-msgstr "Exportar para:"
-
-#: Dialogs/ExportDialog.vala:157
-msgid "Select Folder"
-msgstr "Selecionar pasta"
-
-#: Dialogs/ExportDialog.vala:166
-msgid "Format:"
-msgstr "Formato:"
-
-#: Dialogs/ExportDialog.vala:180
-msgid "Quality:"
-msgstr "Qualidade:"
-
-#: Dialogs/ExportDialog.vala:192
-msgid "Compression:"
-msgstr "Compressão:"
-
-#: Dialogs/ExportDialog.vala:206
-msgid "Transparency:"
-msgstr "Transparência:"
-
-#: Dialogs/ExportDialog.vala:219
-msgid "Scale:"
-msgstr "Escala:"
-
-#: Dialogs/ExportDialog.vala:243 FileFormat/FileManager.vala:49
-#: FileFormat/FileManager.vala:105
-msgid "Cancel"
-msgstr "Cancelar"
-
-#: Dialogs/ExportDialog.vala:250 Dialogs/ShortcutsDialog.vala:63
-#: Layouts/HeaderBar.vala:112
-msgid "Export"
-msgstr "Exportar"
-
-#: Dialogs/ReleaseDialog.vala:47 Dialogs/SettingsDialog.vala:217
-msgid ""
-"WARNING!\n"
-"Akira is still under development and not ready for production. Missing "
-"features, random bugs, and black holes opening in your kitchen are to be "
-"expected."
-msgstr ""
-"ATENÇÃO!\n"
-"Akira está sob desenvolvimento e não está pronto para produção. É de se "
-"esperar o mau funcionamento e a inexistência de algumas funcionalidades."
-
-#: Dialogs/ReleaseDialog.vala:100 Dialogs/SettingsDialog.vala:249
-msgid "Make a Donation"
-msgstr "Doar"
-
-#: Dialogs/ReleaseDialog.vala:109 Dialogs/SettingsDialog.vala:258
-msgid "Suggest Translations"
-msgstr "Sugerir traduções"
-
-#: Dialogs/ReleaseDialog.vala:118 Dialogs/SettingsDialog.vala:267
-msgid "Report a Problem"
-msgstr "Reportar um problema"
-
-#: Dialogs/SettingsDialog.vala:40
-msgid "Preferences"
-msgstr "Preferências"
-
-#: Dialogs/SettingsDialog.vala:50 Dialogs/SettingsDialog.vala:73
-#: Dialogs/ShortcutsDialog.vala:45
-msgid "General"
-msgstr "Geral"
-
-#: Dialogs/SettingsDialog.vala:51 Dialogs/SettingsDialog.vala:86
-msgid "Interface"
-msgstr "Interface"
-
-#: Dialogs/SettingsDialog.vala:52 Layouts/HeaderBar.vala:280
-msgid "Shapes"
-msgstr "Formas"
-
-#: Dialogs/SettingsDialog.vala:53
-msgid "About"
-msgstr "Sobre"
-
-#: Dialogs/SettingsDialog.vala:74
-msgid "Auto Reopen Latest File:"
-msgstr "Reabrir automaticamente arquivo mais recente:"
-
-#: Dialogs/SettingsDialog.vala:88
-msgid "Use Dark Theme:"
-msgstr "Usar tema escuro:"
-
-#: Dialogs/SettingsDialog.vala:92
-msgid "Invert Panels Order:"
-msgstr "Inverter ordem dos painéis:"
-
-#: Dialogs/SettingsDialog.vala:96
-msgid "Restart application to apply this change."
-msgstr "Reinicie a aplicação para aplicar a mudança."
-
-#: Dialogs/SettingsDialog.vala:100
-msgid "ToolBar Style"
-msgstr "Estilo da barra de ferramentas"
-
-#: Dialogs/SettingsDialog.vala:102
-msgid "Show Button Labels:"
-msgstr "Mostrar legendas de botões:"
-
-#: Dialogs/SettingsDialog.vala:106
-msgid "Use Symbolic Icons:"
-msgstr "Usar ícones monocromáticos:"
-
-#: Dialogs/SettingsDialog.vala:129
-msgid "Default Colors"
-msgstr "Cores padrão"
-
-#: Dialogs/SettingsDialog.vala:131
-msgid "Define the default style used when creating a new shape."
-msgstr "Define o estilo padrão a ser usado para criar uma nova forma."
-
-#: Dialogs/SettingsDialog.vala:136
-msgid "Fill Color:"
-msgstr "Cor de preenchimento:"
-
-#: Dialogs/SettingsDialog.vala:157
-msgid "Enable Border Style:"
-msgstr "Ativar estilo com bordas:"
-
-#: Dialogs/SettingsDialog.vala:160
-msgid "Border Color:"
-msgstr "Cor da borda:"
-
-#: Dialogs/SettingsDialog.vala:181
-msgid "Border Width:"
-msgstr "Largura da borda:"
-
-#: Dialogs/SettingsDialog.vala:209
-msgid "The Linux Design Tool"
-msgstr "A ferramenta de design para Linux"
-
-#: Dialogs/SettingsDialog.vala:226
-msgid "Thanks to our awesome supporters!"
-msgstr "Obrigado aos nossos apoiadores incríveis!"
-
-#: Dialogs/SettingsDialog.vala:231
-msgid "View the list of supporters"
-msgstr "Ver lista de apoiadores"
-
-#: Dialogs/ShortcutsDialog.vala:46
-msgid "New window:"
-msgstr "Nova Janela:"
-
-#: Dialogs/ShortcutsDialog.vala:48
-msgid "Preferences:"
-msgstr "Preferências:"
-
-#: Dialogs/ShortcutsDialog.vala:50
-msgid "Quit:"
-msgstr "Sair:"
-
-#: Dialogs/ShortcutsDialog.vala:52
-msgid "Presentation mode:"
-msgstr "Modo de apresentação:"
-
-#: Dialogs/ShortcutsDialog.vala:55
-msgid "File"
-msgstr "Arquivo"
-
-#: Dialogs/ShortcutsDialog.vala:56
-msgid "Open:"
-msgstr "Abrir:"
-
-#: Dialogs/ShortcutsDialog.vala:58
-msgid "Save:"
-msgstr "Salvar:"
-
-#: Dialogs/ShortcutsDialog.vala:60
-msgid "Save as:"
-msgstr "Salvar como:"
-
-#: Dialogs/ShortcutsDialog.vala:64
-msgid "Export artboards:"
-msgstr "Exportar pranchetas:"
-
-#: Dialogs/ShortcutsDialog.vala:66
-msgid "Export selection:"
-msgstr "Exportar seleção:"
-
-#: Dialogs/ShortcutsDialog.vala:68
-msgid "Highlight area to export:"
-msgstr "Selecionar área para exportar:"
-
-#: Dialogs/ShortcutsDialog.vala:77
-msgid "Canvas"
-msgstr "Tela"
-
-#: Dialogs/ShortcutsDialog.vala:78
-msgid "Zoom in:"
-msgstr "Aumentar zoom:"
-
-#: Dialogs/ShortcutsDialog.vala:80
-msgid "Zoom out:"
-msgstr "Reduzir zoom:"
-
-#: Dialogs/ShortcutsDialog.vala:82
-msgid "Zoom reset:"
-msgstr "Redefinir zoom:"
-
-#: Dialogs/ShortcutsDialog.vala:85
-msgid "Item creation"
-msgstr "Criação de item"
-
-#: Dialogs/ShortcutsDialog.vala:86
-msgid "Artboard:"
-msgstr "Prancheta:"
-
-#: Dialogs/ShortcutsDialog.vala:88
-msgid "Rectangle:"
-msgstr "Retângulo:"
-
-#: Dialogs/ShortcutsDialog.vala:90
-msgid "Ellipse:"
-msgstr "Elipse:"
-
-#: Dialogs/ShortcutsDialog.vala:92
-msgid "Text:"
-msgstr "Texto:"
-
-#: Dialogs/ShortcutsDialog.vala:94
-msgid "Image:"
-msgstr "Imagem:"
-
-#: Dialogs/ShortcutsDialog.vala:97 Layouts/Partials/TransformPanel.vala:174
-msgid "Transform"
-msgstr "Transformar"
-
-#: Dialogs/ShortcutsDialog.vala:98
-msgid "Raise selection:"
-msgstr "Subir seleção:"
-
-#: Dialogs/ShortcutsDialog.vala:100
-msgid "Lower selection:"
-msgstr "Descer seleção:"
-
-#: Dialogs/ShortcutsDialog.vala:102
-msgid "Raise selection to top:"
-msgstr "Trazer seleção para frente:"
-
-#: Dialogs/ShortcutsDialog.vala:104
-msgid "Lower selection to bottom:"
-msgstr "Enviar seleção para trás:"
-
-#: Dialogs/ShortcutsDialog.vala:106
-msgid "Flip horizontally:"
-msgstr "Inverter horizontalmente:"
-
-#: Dialogs/ShortcutsDialog.vala:108
-msgid "Flip vertically:"
-msgstr "Inverter verticalmente:"
-
-#: FileFormat/FileManager.vala:46
-msgid "Save Akira file"
-msgstr "Salvar arquivo Akira"
-
-#: FileFormat/FileManager.vala:48 Layouts/HeaderBar.vala:190
-msgid "Save"
-msgstr "Salvar"
-
-#: FileFormat/FileManager.vala:71
-msgid "Akira files"
-msgstr "Arquivos Akira"
-
-#: FileFormat/FileManager.vala:76
-msgid "All files"
-msgstr "Todos os arquivos"
-
-#: FileFormat/FileManager.vala:103
-msgid "Open Akira file"
-msgstr "Abrir arquivo Akira"
-
-#: FileFormat/FileManager.vala:105 Layouts/HeaderBar.vala:170
-msgid "Open"
-msgstr "Abrir"
-
-#: Layouts/HeaderBar.vala:69 Lib/Managers/ExportManager.vala:296
-msgid "Untitled"
-msgstr "Sem título"
-
-#: Layouts/HeaderBar.vala:71
-msgid "Menu"
-msgstr "Menu"
-
-#: Layouts/HeaderBar.vala:75
-msgid "Insert"
-msgstr "Inserir"
-
-#: Layouts/HeaderBar.vala:82
-msgid "Group"
-msgstr "Agrupar"
-
-#: Layouts/HeaderBar.vala:84
-msgid "Ungroup"
-msgstr "Desagrupar"
-
-#: Layouts/HeaderBar.vala:87
-msgid "Up"
-msgstr "Cima"
-
-#: Layouts/HeaderBar.vala:92
-msgid "Down"
-msgstr "Baixo"
-
-#: Layouts/HeaderBar.vala:97
-msgid "Top"
-msgstr "Acima"
-
-#: Layouts/HeaderBar.vala:102
-msgid "Bottom"
-msgstr "Abaixo"
-
-#: Layouts/HeaderBar.vala:107
-msgid "Settings"
-msgstr "Configuração"
-
-#: Layouts/HeaderBar.vala:118
-msgid "Difference"
-msgstr "Diferença"
-
-#: Layouts/HeaderBar.vala:120
-msgid "Exclusion"
-msgstr "Exclusão"
-
-#: Layouts/HeaderBar.vala:122
-msgid "Intersect"
-msgstr "Interseção"
-
-#: Layouts/HeaderBar.vala:124
-msgid "Union"
-msgstr "União"
-
-#: Layouts/HeaderBar.vala:161
-msgid "New Window"
-msgstr "Nova Janela"
-
-#: Layouts/HeaderBar.vala:182
-msgid "Open Recent"
-msgstr "Abrir Recente"
-
-#: Layouts/HeaderBar.vala:195
-msgid "Save As"
-msgstr "Salvar Como"
-
-#: Layouts/HeaderBar.vala:204
-msgid "Quit"
-msgstr "Sair"
-
-#: Layouts/HeaderBar.vala:237
-msgid "Artboard"
-msgstr "Prancheta"
-
-#: Layouts/HeaderBar.vala:254
-msgid "Add Items"
-msgstr "Adicionar Itens"
-
-#: Layouts/HeaderBar.vala:262
-msgid "Rectangle"
-msgstr "Retângulo"
-
-#: Layouts/HeaderBar.vala:268
-msgid "Ellipse"
-msgstr "Elipse"
-
-#: Layouts/HeaderBar.vala:286
-msgid "Vector"
-msgstr "Vetor"
-
-#: Layouts/HeaderBar.vala:288
-msgid "Pencil"
-msgstr "Lápis"
-
-#: Layouts/HeaderBar.vala:291
-msgid "Text"
-msgstr "Texto"
-
-#: Layouts/HeaderBar.vala:297
-msgid "Image"
-msgstr "Imagem"
-
-#: Layouts/HeaderBar.vala:330
-msgid "Export Current Selection"
-msgstr "Exportar Seleção Atual"
-
-#: Layouts/HeaderBar.vala:336
-msgid "Export Artboards"
-msgstr "Exportar Pranchetas"
-
-#: Layouts/HeaderBar.vala:345
-msgid "Highlight Area to Export"
-msgstr "Selecionar Área para Exportar"
-
-#: Layouts/HeaderBar.vala:391
-msgid "Main Menu"
-msgstr "Menu Principal"
-
-#: Layouts/HeaderBar.vala:468 Services/ActionManager.vala:218
-#: Services/ActionManager.vala:237 Services/ActionManager.vala:256
-#, c-format
-msgid "Unable to open file at '%s'"
-msgstr "Não foi possível abrir o arquivo em «%s»"
-
-#: Layouts/MainCanvas.vala:52
-msgid "Button was pressed!"
-msgstr "Botão pressionado!"
-
-#: Layouts/MainCanvas.vala:160
-msgid "Export completed!"
-msgstr "Exportação finalizada!"
-
-#: Layouts/Partials/AlignItemsPanel.vala:48
-msgid "Distribute Horizontally"
-msgstr "Distribuir Horizontalmente"
-
-#: Layouts/Partials/AlignItemsPanel.vala:50
-msgid "Distribute Vertically"
-msgstr "Distribuir Verticalmente"
-
-#: Layouts/Partials/AlignItemsPanel.vala:52
-msgid "Align Left"
-msgstr "Alinhar à Esquerda"
-
-#: Layouts/Partials/AlignItemsPanel.vala:53
-msgid "Align Center"
-msgstr "Alinhar Horizontalmente"
-
-#: Layouts/Partials/AlignItemsPanel.vala:54
-msgid "Align Right"
-msgstr "Alinhar à Direita"
-
-#: Layouts/Partials/AlignItemsPanel.vala:56
-msgid "Align Top"
-msgstr "Alinhar Acima"
-
-#: Layouts/Partials/AlignItemsPanel.vala:57
-msgid "Align Middle"
-msgstr "Centralizar Verticalmente"
-
-#: Layouts/Partials/AlignItemsPanel.vala:58
-msgid "Align Bottom"
-msgstr "Alinhar Abaixo"
-
-#: Layouts/Partials/Artboard.vala:144 Layouts/Partials/Artboard.vala:487
-#: Layouts/Partials/Layer.vala:139 Layouts/Partials/Layer.vala:687
-msgid "Lock Layer"
-msgstr "Bloquear Camada"
-
-#: Layouts/Partials/Artboard.vala:155 Layouts/Partials/Artboard.vala:529
-#: Layouts/Partials/Layer.vala:156 Layouts/Partials/Layer.vala:729
-msgid "Hide Layer"
-msgstr "Ocultar Camada"
-
-#: Layouts/Partials/Artboard.vala:487 Layouts/Partials/Layer.vala:687
-msgid "Unlock Layer"
-msgstr "Desbloquear Camada"
-
-#: Layouts/Partials/Artboard.vala:529 Layouts/Partials/Layer.vala:729
-msgid "Show Layer"
-msgstr "Mostrar Camada"
-
-#: Layouts/Partials/BorderRadiusPanel.vala:86
-msgid "Style"
-msgstr "Estilo"
-
-#: Layouts/Partials/BorderRadiusPanel.vala:103
-msgid "Border Radius"
-msgstr "Raio da Borda"
-
-#: Layouts/Partials/BorderRadiusPanel.vala:198
-msgid "Autoscale Corners"
-msgstr "Escalar Cantos Automaticamente"
-
-#: Layouts/Partials/BorderRadiusPanel.vala:207
-msgid "Uniform Corners"
-msgstr "Cantos Uniformes"
-
-#: Layouts/Partials/BordersPanel.vala:53
-msgid "Borders"
-msgstr "Bordas"
-
-#: Layouts/Partials/FillsPanel.vala:54
-msgid "Fills"
-msgstr "Preenchimentos"
-
-#: Layouts/Partials/TransformPanel.vala:96
-msgid "X"
-msgstr "X"
-
-#: Layouts/Partials/TransformPanel.vala:96
-msgid "Horizontal position"
-msgstr "Posição horizontal"
-
-#: Layouts/Partials/TransformPanel.vala:98
-msgid "Y"
-msgstr "Y"
-
-#: Layouts/Partials/TransformPanel.vala:98
-msgid "Vertical position"
-msgstr "Posição vertical"
-
-#: Layouts/Partials/TransformPanel.vala:100
-msgid "W"
-msgstr "↔"
-
-#: Layouts/Partials/TransformPanel.vala:100
-msgid "Width"
-msgstr "Largura"
-
-#: Layouts/Partials/TransformPanel.vala:102
-msgid "H"
-msgstr "↕"
-
-#: Layouts/Partials/TransformPanel.vala:102
-msgid "Height"
-msgstr "Altura"
-
-#: Layouts/Partials/TransformPanel.vala:107
-msgid "Lock Ratio"
-msgstr "Bloquear Aspecto"
-
-#: Layouts/Partials/TransformPanel.vala:114
-msgid "R"
-msgstr "↻"
-
-#: Layouts/Partials/TransformPanel.vala:114
-msgid "Rotation degrees"
-msgstr "Graus de rotação"
-
-#: Layouts/Partials/TransformPanel.vala:126
-msgid "Flip Horizontally"
-msgstr "Inverter Horizontalmente"
-
-#: Layouts/Partials/TransformPanel.vala:137
-msgid "Flip Vertically"
-msgstr "Inverter Verticalmente"
-
-#: Layouts/Partials/TransformPanel.vala:165
-msgid "Position"
-msgstr "Posição"
-
-#: Layouts/Partials/TransformPanel.vala:169
-msgid "Size"
-msgstr "Tamanho"
-
-#: Layouts/Partials/TransformPanel.vala:178
-msgid "Opacity"
-msgstr "Opacidade"
-
-#: Layouts/RightSideBar.vala:111
-msgid "Search Layer"
-msgstr "Buscar Camada"
-
-#: Lib/Managers/ExportManager.vala:192 Lib/Managers/ExportManager.vala:219
-msgid "Generating preview, please wait…"
-msgstr "Gerando pré-visualização, aguarde por favor…"
-
-#: Lib/Managers/ExportManager.vala:313
-#, c-format
-msgid "Untitled %i"
-msgstr "Sem título %i"
-
-#: Lib/Managers/ExportManager.vala:484
-msgid "Exporting images…"
-msgstr "Exportando imagens…"
-
-#: Partials/ExportWidget.vala:117
-#, c-format
-msgid "%i × %i px · %s"
-msgstr "%i × %i px · %s"
-
-#: Partials/ExportWidget.vala:124
-msgid "Fetching image size…"
-msgstr "Recuperando tamanho de imagem…"
-
-#: Partials/ZoomButton.vala:49
-msgid "Zoom Out"
-msgstr "Reduzir Zoom"
-
-#: Partials/ZoomButton.vala:55
-msgid "Reset Zoom"
-msgstr "Redefinir Zoom"
-
-#: Partials/ZoomButton.vala:62
-msgid "Zoom In"
-msgstr "Aumentar Zoom"
-
-#: Partials/ZoomButton.vala:68
-msgid "Zoom"
-msgstr "Zoom"
-
-#: Services/ActionManager.vala:211
-msgid "No recently opened file available!"
-msgstr "Não há arquivos recentes!"
-
-#: Services/ActionManager.vala:230
-msgid "No second most recently opened file available!"
-msgstr "Não há nenhum segundo arquivo recente!"
-
-#: Services/ActionManager.vala:249
-msgid "No third most recently opened file available!"
-msgstr "Não há nenhum terceiro arquivo recente!"
-
-#: Services/ActionManager.vala:287
-msgid "Nothing selected to export!"
-msgstr "Nada selecionado para exportar!"
-
-#: Services/ActionManager.vala:296
-msgid "Export of Artboards currently unavailable…sorry 😑️"
-msgstr "Exportação de Pranchetas atualmente está indisponível... 😑️"
-
-#: Services/ActionManager.vala:363
-msgid "Choose image file"
-msgstr "Selecionar um arquivo de imagem"
-
-#: Services/ActionManager.vala:363
-msgid "Select"
-msgstr "Selecionar"
-
-#: Services/ActionManager.vala:363
-msgid "Close"
-msgstr "Fechar"
-
-#: Services/ActionManager.vala:432
-#, c-format
-msgid "Error! .%s files are not supported!"
-msgstr "Erro! Arquivos .%s não são suportados!"
-
-#: Window.vala:119
-msgid "Are you sure you want to quit?"
-msgstr "Tem certeza que quer sair?"
-
-#: Window.vala:120
-msgid "All unsaved data will be lost and impossible to recover."
-msgstr ""
-"Todos os dados não salvos serão perdidos e será impossível recuperar."
-
-#: Window.vala:122
-msgid "Quit without saving!"
-msgstr "Sair sem salvar!"
-
-#: Window.vala:123
-msgid "Save file"
-msgstr "Salvar arquivo"
diff --git a/po/qu.po b/po/qu.po
deleted file mode 100644
index 7d7bf5d53..000000000
--- a/po/qu.po
+++ /dev/null
@@ -1,4 +0,0 @@
-msgid ""
-msgstr ""
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
diff --git a/po/rm.po b/po/rm.po
deleted file mode 100644
index 7d7bf5d53..000000000
--- a/po/rm.po
+++ /dev/null
@@ -1,4 +0,0 @@
-msgid ""
-msgstr ""
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
diff --git a/po/rn.po b/po/rn.po
deleted file mode 100644
index 7d7bf5d53..000000000
--- a/po/rn.po
+++ /dev/null
@@ -1,4 +0,0 @@
-msgid ""
-msgstr ""
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
diff --git a/po/ro.po b/po/ro.po
deleted file mode 100644
index a66282f54..000000000
--- a/po/ro.po
+++ /dev/null
@@ -1,5 +0,0 @@
-msgid ""
-msgstr ""
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
-"Plural-Forms: nplurals=3; plural=n==1 ? 0 : (n==0 || (n%100 > 0 && n%100 < 20)) ? 1 : 2;\n"
diff --git a/po/ru.po b/po/ru.po
deleted file mode 100644
index 6188ef853..000000000
--- a/po/ru.po
+++ /dev/null
@@ -1,5 +0,0 @@
-msgid ""
-msgstr ""
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
-"Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n"
diff --git a/po/rue.po b/po/rue.po
deleted file mode 100644
index 7d7bf5d53..000000000
--- a/po/rue.po
+++ /dev/null
@@ -1,4 +0,0 @@
-msgid ""
-msgstr ""
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
diff --git a/po/rw.po b/po/rw.po
deleted file mode 100644
index 7d7bf5d53..000000000
--- a/po/rw.po
+++ /dev/null
@@ -1,4 +0,0 @@
-msgid ""
-msgstr ""
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
diff --git a/po/sa.po b/po/sa.po
deleted file mode 100644
index 7d7bf5d53..000000000
--- a/po/sa.po
+++ /dev/null
@@ -1,4 +0,0 @@
-msgid ""
-msgstr ""
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
diff --git a/po/sc.po b/po/sc.po
deleted file mode 100644
index 7d7bf5d53..000000000
--- a/po/sc.po
+++ /dev/null
@@ -1,4 +0,0 @@
-msgid ""
-msgstr ""
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
diff --git a/po/sd.po b/po/sd.po
deleted file mode 100644
index 7d7bf5d53..000000000
--- a/po/sd.po
+++ /dev/null
@@ -1,4 +0,0 @@
-msgid ""
-msgstr ""
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
diff --git a/po/se.po b/po/se.po
deleted file mode 100644
index 7d7bf5d53..000000000
--- a/po/se.po
+++ /dev/null
@@ -1,4 +0,0 @@
-msgid ""
-msgstr ""
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
diff --git a/po/sg.po b/po/sg.po
deleted file mode 100644
index 7d7bf5d53..000000000
--- a/po/sg.po
+++ /dev/null
@@ -1,4 +0,0 @@
-msgid ""
-msgstr ""
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
diff --git a/po/si.po b/po/si.po
deleted file mode 100644
index 7d7bf5d53..000000000
--- a/po/si.po
+++ /dev/null
@@ -1,4 +0,0 @@
-msgid ""
-msgstr ""
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
diff --git a/po/sk.po b/po/sk.po
deleted file mode 100644
index fb0b545a5..000000000
--- a/po/sk.po
+++ /dev/null
@@ -1,5 +0,0 @@
-msgid ""
-msgstr ""
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
-"Plural-Forms: nplurals=3; plural=(n==1) ? 0 : (n>=2 && n<=4) ? 1 : 2;\n"
diff --git a/po/sl.po b/po/sl.po
deleted file mode 100644
index 1a8e08ebf..000000000
--- a/po/sl.po
+++ /dev/null
@@ -1,5 +0,0 @@
-msgid ""
-msgstr ""
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
-"Plural-Forms: nplurals=4; plural=n%100==1 ? 0 : n%100==2 ? 1 : n%100==3 || n%100==4 ? 2 : 3;\n"
diff --git a/po/sm.po b/po/sm.po
deleted file mode 100644
index 7d7bf5d53..000000000
--- a/po/sm.po
+++ /dev/null
@@ -1,4 +0,0 @@
-msgid ""
-msgstr ""
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
diff --git a/po/sma.po b/po/sma.po
deleted file mode 100644
index 7d7bf5d53..000000000
--- a/po/sma.po
+++ /dev/null
@@ -1,4 +0,0 @@
-msgid ""
-msgstr ""
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
diff --git a/po/sn.po b/po/sn.po
deleted file mode 100644
index 7d7bf5d53..000000000
--- a/po/sn.po
+++ /dev/null
@@ -1,4 +0,0 @@
-msgid ""
-msgstr ""
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
diff --git a/po/so.po b/po/so.po
deleted file mode 100644
index 7d7bf5d53..000000000
--- a/po/so.po
+++ /dev/null
@@ -1,4 +0,0 @@
-msgid ""
-msgstr ""
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
diff --git a/po/sq.po b/po/sq.po
deleted file mode 100644
index 7d7bf5d53..000000000
--- a/po/sq.po
+++ /dev/null
@@ -1,4 +0,0 @@
-msgid ""
-msgstr ""
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
diff --git a/po/sr.po b/po/sr.po
deleted file mode 100644
index 6188ef853..000000000
--- a/po/sr.po
+++ /dev/null
@@ -1,5 +0,0 @@
-msgid ""
-msgstr ""
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
-"Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n"
diff --git a/po/ss.po b/po/ss.po
deleted file mode 100644
index 7d7bf5d53..000000000
--- a/po/ss.po
+++ /dev/null
@@ -1,4 +0,0 @@
-msgid ""
-msgstr ""
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
diff --git a/po/st.po b/po/st.po
deleted file mode 100644
index 7d7bf5d53..000000000
--- a/po/st.po
+++ /dev/null
@@ -1,4 +0,0 @@
-msgid ""
-msgstr ""
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
diff --git a/po/su.po b/po/su.po
deleted file mode 100644
index 7d7bf5d53..000000000
--- a/po/su.po
+++ /dev/null
@@ -1,4 +0,0 @@
-msgid ""
-msgstr ""
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
diff --git a/po/sv.po b/po/sv.po
deleted file mode 100644
index ca301d2fd..000000000
--- a/po/sv.po
+++ /dev/null
@@ -1,5 +0,0 @@
-msgid ""
-msgstr ""
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
-"Plural-Forms: nplurals=2; plural=n != 1;\n"
diff --git a/po/sw.po b/po/sw.po
deleted file mode 100644
index 7d7bf5d53..000000000
--- a/po/sw.po
+++ /dev/null
@@ -1,4 +0,0 @@
-msgid ""
-msgstr ""
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
diff --git a/po/ta.po b/po/ta.po
deleted file mode 100644
index 7d7bf5d53..000000000
--- a/po/ta.po
+++ /dev/null
@@ -1,4 +0,0 @@
-msgid ""
-msgstr ""
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
diff --git a/po/te.po b/po/te.po
deleted file mode 100644
index 7d7bf5d53..000000000
--- a/po/te.po
+++ /dev/null
@@ -1,4 +0,0 @@
-msgid ""
-msgstr ""
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
diff --git a/po/tg.po b/po/tg.po
deleted file mode 100644
index 7d7bf5d53..000000000
--- a/po/tg.po
+++ /dev/null
@@ -1,4 +0,0 @@
-msgid ""
-msgstr ""
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
diff --git a/po/th.po b/po/th.po
deleted file mode 100644
index 7d7bf5d53..000000000
--- a/po/th.po
+++ /dev/null
@@ -1,4 +0,0 @@
-msgid ""
-msgstr ""
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
diff --git a/po/ti.po b/po/ti.po
deleted file mode 100644
index 7d7bf5d53..000000000
--- a/po/ti.po
+++ /dev/null
@@ -1,4 +0,0 @@
-msgid ""
-msgstr ""
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
diff --git a/po/tk.po b/po/tk.po
deleted file mode 100644
index 7d7bf5d53..000000000
--- a/po/tk.po
+++ /dev/null
@@ -1,4 +0,0 @@
-msgid ""
-msgstr ""
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
diff --git a/po/tl.po b/po/tl.po
deleted file mode 100644
index 7d7bf5d53..000000000
--- a/po/tl.po
+++ /dev/null
@@ -1,4 +0,0 @@
-msgid ""
-msgstr ""
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
diff --git a/po/tn.po b/po/tn.po
deleted file mode 100644
index 7d7bf5d53..000000000
--- a/po/tn.po
+++ /dev/null
@@ -1,4 +0,0 @@
-msgid ""
-msgstr ""
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
diff --git a/po/to.po b/po/to.po
deleted file mode 100644
index 7d7bf5d53..000000000
--- a/po/to.po
+++ /dev/null
@@ -1,4 +0,0 @@
-msgid ""
-msgstr ""
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
diff --git a/po/tr.po b/po/tr.po
deleted file mode 100644
index 5f33969bb..000000000
--- a/po/tr.po
+++ /dev/null
@@ -1,717 +0,0 @@
-msgid ""
-msgstr ""
-"Project-Id-Version: \n"
-"POT-Creation-Date: 2020-09-27 19:02+0300\n"
-"PO-Revision-Date: \n"
-"Language-Team: \n"
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
-"Content-Transfer-Encoding: 8bit\n"
-"Plural-Forms: nplurals=2; plural=(n != 1);\n"
-"X-Generator: Poedit 2.4.1\n"
-"X-Poedit-Basepath: ../src\n"
-"Last-Translator: Nazım Gediz Aydındoğmuş \n"
-"Language: tr\n"
-"X-Poedit-SearchPath-0: .\n"
-
-#: Dialogs/ExportDialog.vala:151
-msgid "Export to:"
-msgstr "Aktarılacak konum:"
-
-#: Dialogs/ExportDialog.vala:157
-msgid "Select Folder"
-msgstr "Dizin Seç"
-
-#: Dialogs/ExportDialog.vala:166
-msgid "Format:"
-msgstr "Biçim:"
-
-#: Dialogs/ExportDialog.vala:179
-msgid "Quality:"
-msgstr "Kalite:"
-
-#: Dialogs/ExportDialog.vala:191
-msgid "Compression:"
-msgstr "Sıkıştırma:"
-
-#: Dialogs/ExportDialog.vala:205
-msgid "Transparency:"
-msgstr "Saydamlık:"
-
-#: Dialogs/ExportDialog.vala:218
-msgid "Scale:"
-msgstr "Ölçek:"
-
-#: Dialogs/ExportDialog.vala:242 FileFormat/FileManager.vala:49
-#: FileFormat/FileManager.vala:105
-msgid "Cancel"
-msgstr "İptal"
-
-#: Dialogs/ExportDialog.vala:249 Dialogs/ShortcutsDialog.vala:63
-#: Layouts/HeaderBar.vala:112
-msgid "Export"
-msgstr "Dışarı Aktar"
-
-#: Dialogs/ReleaseDialog.vala:47 Dialogs/SettingsDialog.vala:217
-msgid ""
-"WARNING!\n"
-"Akira is still under development and not ready for production. Missing "
-"features, random bugs, and black holes opening in your kitchen are to be "
-"expected."
-msgstr ""
-"UYARI!\n"
-"Akira hala geliştirme aşamasındadır ve son ürün oluşturmaya yönelik "
-"kullanıma hazır değildir. Kullanım esnasında eksik özellikler, rastgele "
-"hatalar ve mutfağınızda zuhur eden kara delikler ile karşılaşabilirsiniz."
-
-#: Dialogs/ReleaseDialog.vala:100 Dialogs/SettingsDialog.vala:249
-msgid "Make a Donation"
-msgstr "Bağış Yap"
-
-#: Dialogs/ReleaseDialog.vala:109 Dialogs/SettingsDialog.vala:258
-msgid "Suggest Translations"
-msgstr "Çeviri Öner"
-
-#: Dialogs/ReleaseDialog.vala:118 Dialogs/SettingsDialog.vala:267
-msgid "Report a Problem"
-msgstr "Sorun Bildir"
-
-#: Dialogs/SettingsDialog.vala:40
-msgid "Preferences"
-msgstr "Tercihler"
-
-#: Dialogs/SettingsDialog.vala:50 Dialogs/SettingsDialog.vala:73
-#: Dialogs/ShortcutsDialog.vala:45
-msgid "General"
-msgstr "Genel"
-
-#: Dialogs/SettingsDialog.vala:51 Dialogs/SettingsDialog.vala:86
-msgid "Interface"
-msgstr "Arayüz"
-
-#: Dialogs/SettingsDialog.vala:52 Layouts/HeaderBar.vala:280
-msgid "Shapes"
-msgstr "Şekiller"
-
-#: Dialogs/SettingsDialog.vala:53
-msgid "About"
-msgstr "Hakkında"
-
-#: Dialogs/SettingsDialog.vala:74
-msgid "Auto Reopen Latest File:"
-msgstr "Başlangıçta Son Dosyayı Aç:"
-
-#: Dialogs/SettingsDialog.vala:88
-msgid "Use Dark Theme:"
-msgstr "Karanlık Temayı Kullan:"
-
-#: Dialogs/SettingsDialog.vala:92
-msgid "Invert Panels Order:"
-msgstr "Panel Düzenini Tersine Çevir:"
-
-#: Dialogs/SettingsDialog.vala:96
-msgid "Restart application to apply this change."
-msgstr ""
-"Bu değişikliği geçerli hale getirmek için uygulamayı yeniden başlat."
-
-#: Dialogs/SettingsDialog.vala:100
-msgid "ToolBar Style"
-msgstr "Araç Çubuğu Biçimi"
-
-#: Dialogs/SettingsDialog.vala:102
-msgid "Show Button Labels:"
-msgstr "Buton Metinlerini Göster:"
-
-#: Dialogs/SettingsDialog.vala:106
-msgid "Use Symbolic Icons:"
-msgstr "Sembolik Simgeleri Kullan:"
-
-#: Dialogs/SettingsDialog.vala:129
-msgid "Default Colors"
-msgstr "Varsayılan Renkler"
-
-#: Dialogs/SettingsDialog.vala:131
-msgid "Define the default style used when creating a new shape."
-msgstr ""
-"Yeni bir simge oluşturulurken kullanılacak varsayılan biçimi tanımla."
-
-#: Dialogs/SettingsDialog.vala:136
-msgid "Fill Color:"
-msgstr "Dolgu Rengi:"
-
-#: Dialogs/SettingsDialog.vala:157
-msgid "Enable Border Style:"
-msgstr "Kenar Biçimini Etkinleştir:"
-
-#: Dialogs/SettingsDialog.vala:160
-msgid "Border Color:"
-msgstr "Kenar Rengi:"
-
-#: Dialogs/SettingsDialog.vala:181
-msgid "Border Width:"
-msgstr "Kenar Genişliği:"
-
-#: Dialogs/SettingsDialog.vala:209
-msgid "The Linux Design Tool"
-msgstr "Linux'un Tasarım Aracı"
-
-#: Dialogs/SettingsDialog.vala:226
-msgid "Thanks to our awesome supporters!"
-msgstr "Harika destekçilerimiz sayesinde!"
-
-#: Dialogs/SettingsDialog.vala:231
-msgid "View the list of supporters"
-msgstr "Destekleyenlerin listesini görüntüle"
-
-#: Dialogs/ShortcutsDialog.vala:46
-msgid "New window:"
-msgstr "Yeni pencere:"
-
-#: Dialogs/ShortcutsDialog.vala:48
-msgid "Preferences:"
-msgstr "Tercihler:"
-
-#: Dialogs/ShortcutsDialog.vala:50
-msgid "Quit:"
-msgstr "Çıkış Yap:"
-
-#: Dialogs/ShortcutsDialog.vala:52
-msgid "Presentation mode:"
-msgstr "Sunum modu:"
-
-#: Dialogs/ShortcutsDialog.vala:55
-msgid "File"
-msgstr "Dosya"
-
-#: Dialogs/ShortcutsDialog.vala:56
-msgid "Open:"
-msgstr "Aç:"
-
-#: Dialogs/ShortcutsDialog.vala:58
-msgid "Save:"
-msgstr "Kaydet:"
-
-#: Dialogs/ShortcutsDialog.vala:60
-msgid "Save as:"
-msgstr "Farklı Kaydet:"
-
-#: Dialogs/ShortcutsDialog.vala:64
-msgid "Export artboards:"
-msgstr "Çalışma yüzeylerini dışarı aktar:"
-
-#: Dialogs/ShortcutsDialog.vala:66
-msgid "Export selection:"
-msgstr "Seçimi dışarı aktar:"
-
-#: Dialogs/ShortcutsDialog.vala:68
-msgid "Highlight area to export:"
-msgstr "Dışa aktarılacak alanı vurgula:"
-
-#: Dialogs/ShortcutsDialog.vala:77
-msgid "Canvas"
-msgstr "Tuval"
-
-#: Dialogs/ShortcutsDialog.vala:78
-msgid "Zoom in:"
-msgstr "Büyüt:"
-
-#: Dialogs/ShortcutsDialog.vala:80
-msgid "Zoom out:"
-msgstr "Küçült:"
-
-#: Dialogs/ShortcutsDialog.vala:82
-msgid "Zoom reset:"
-msgstr "Yakınlaştırmayı sıfırla:"
-
-#: Dialogs/ShortcutsDialog.vala:85
-msgid "Item creation"
-msgstr "Öğe oluşturma"
-
-#: Dialogs/ShortcutsDialog.vala:86
-msgid "Artboard:"
-msgstr "Çalışma yüzeyi:"
-
-#: Dialogs/ShortcutsDialog.vala:88
-msgid "Rectangle:"
-msgstr "Dikdörtgen:"
-
-#: Dialogs/ShortcutsDialog.vala:90
-msgid "Ellipse:"
-msgstr "Elips:"
-
-#: Dialogs/ShortcutsDialog.vala:92
-msgid "Text:"
-msgstr "Metin:"
-
-#: Dialogs/ShortcutsDialog.vala:94
-msgid "Image:"
-msgstr "Resim:"
-
-#: Dialogs/ShortcutsDialog.vala:97 Layouts/Partials/TransformPanel.vala:174
-msgid "Transform"
-msgstr "Dönüştürme"
-
-#: Dialogs/ShortcutsDialog.vala:98
-msgid "Raise selection:"
-msgstr "Seçimi yükselt:"
-
-#: Dialogs/ShortcutsDialog.vala:100
-msgid "Lower selection:"
-msgstr "Seçimi alçalt:"
-
-#: Dialogs/ShortcutsDialog.vala:102
-msgid "Raise selection to top:"
-msgstr "Seçimi en öne getir:"
-
-#: Dialogs/ShortcutsDialog.vala:104
-msgid "Lower selection to bottom:"
-msgstr "Seçimi en arkaya gönder:"
-
-#: Dialogs/ShortcutsDialog.vala:106
-msgid "Flip horizontally:"
-msgstr "Yatay olarak çevir:"
-
-#: Dialogs/ShortcutsDialog.vala:108
-msgid "Flip vertically:"
-msgstr "Dikey olarak çevir:"
-
-#: FileFormat/FileManager.vala:46
-msgid "Save Akira file"
-msgstr "Akira dosyasını kaydet"
-
-#: FileFormat/FileManager.vala:48 Layouts/HeaderBar.vala:190
-msgid "Save"
-msgstr "Kaydet"
-
-#: FileFormat/FileManager.vala:71
-msgid "Akira files"
-msgstr "Akira dosyaları"
-
-#: FileFormat/FileManager.vala:76
-msgid "All files"
-msgstr "Tüm dosyalar"
-
-#: FileFormat/FileManager.vala:103
-msgid "Open Akira file"
-msgstr "Akira dosyasını aç"
-
-#: FileFormat/FileManager.vala:105 Layouts/HeaderBar.vala:170
-msgid "Open"
-msgstr "Aç"
-
-#: Layouts/HeaderBar.vala:69 Lib/Managers/ExportManager.vala:296
-msgid "Untitled"
-msgstr "İsimsiz"
-
-#: Layouts/HeaderBar.vala:71
-msgid "Menu"
-msgstr "Menü"
-
-#: Layouts/HeaderBar.vala:75
-msgid "Insert"
-msgstr "Ekle"
-
-#: Layouts/HeaderBar.vala:82
-msgid "Group"
-msgstr "Gruplandır"
-
-#: Layouts/HeaderBar.vala:84
-msgid "Ungroup"
-msgstr "Grubu dağıt"
-
-#: Layouts/HeaderBar.vala:87
-msgid "Up"
-msgstr "Yukarı"
-
-#: Layouts/HeaderBar.vala:92
-msgid "Down"
-msgstr "Aşağı"
-
-#: Layouts/HeaderBar.vala:97
-msgid "Top"
-msgstr "Üst"
-
-#: Layouts/HeaderBar.vala:102
-msgid "Bottom"
-msgstr "Alt"
-
-#: Layouts/HeaderBar.vala:107
-msgid "Settings"
-msgstr "Ayarlar"
-
-#: Layouts/HeaderBar.vala:118
-msgid "Difference"
-msgstr "Fark"
-
-#: Layouts/HeaderBar.vala:120
-msgid "Exclusion"
-msgstr "Dışlama"
-
-#: Layouts/HeaderBar.vala:122
-msgid "Intersect"
-msgstr "Kesişim"
-
-#: Layouts/HeaderBar.vala:124
-msgid "Union"
-msgstr "Birleşim"
-
-#: Layouts/HeaderBar.vala:161
-msgid "New Window"
-msgstr "Yeni Pencere"
-
-#: Layouts/HeaderBar.vala:182
-msgid "Open Recent"
-msgstr "Son Kullanılan"
-
-#: Layouts/HeaderBar.vala:195
-msgid "Save As"
-msgstr "Farklı Kaydet"
-
-#: Layouts/HeaderBar.vala:204
-msgid "Quit"
-msgstr "Çıkış Yap"
-
-#: Layouts/HeaderBar.vala:237
-msgid "Artboard"
-msgstr "Çalışma Yüzeyi"
-
-#: Layouts/HeaderBar.vala:254
-msgid "Add Items"
-msgstr "Öğeleri Ekle"
-
-#: Layouts/HeaderBar.vala:262
-msgid "Rectangle"
-msgstr "Dikdörtgen"
-
-#: Layouts/HeaderBar.vala:268
-msgid "Ellipse"
-msgstr "Elips"
-
-#: Layouts/HeaderBar.vala:286
-msgid "Vector"
-msgstr "Vektör"
-
-#: Layouts/HeaderBar.vala:288
-msgid "Pencil"
-msgstr "Kalem"
-
-#: Layouts/HeaderBar.vala:291
-msgid "Text"
-msgstr "Metin"
-
-#: Layouts/HeaderBar.vala:297
-msgid "Image"
-msgstr "Resim"
-
-#: Layouts/HeaderBar.vala:330
-msgid "Export Current Selection"
-msgstr "Mevcut Seçimi Dışarı Aktar"
-
-#: Layouts/HeaderBar.vala:336
-msgid "Export Artboards"
-msgstr "Çalışma Yüzeylerini Dışarı Aktar"
-
-#: Layouts/HeaderBar.vala:345
-msgid "Highlight Area to Export"
-msgstr "Dışa Aktarılacak Alanı Vurgula"
-
-#: Layouts/HeaderBar.vala:391
-msgid "Main Menu"
-msgstr "Ana Menü"
-
-#: Layouts/HeaderBar.vala:468 Services/ActionManager.vala:224
-#: Services/ActionManager.vala:243 Services/ActionManager.vala:262
-#, c-format
-msgid "Unable to open file at '%s'"
-msgstr "'%s' konumundaki dosya açılamıyor"
-
-#: Layouts/MainCanvas.vala:46
-msgid "Button was pressed!"
-msgstr "Butona basıldı!"
-
-#: Layouts/MainCanvas.vala:206
-msgid "Export completed!"
-msgstr "Dışarı aktarma tamamlandı!"
-
-#: Layouts/Partials/AlignItemsPanel.vala:48
-msgid "Distribute Horizontally"
-msgstr "Yatay Olarak Dağıt"
-
-#: Layouts/Partials/AlignItemsPanel.vala:50
-msgid "Distribute Vertically"
-msgstr "Dikey Olarak Dağıt"
-
-#: Layouts/Partials/AlignItemsPanel.vala:52
-msgid "Align Left"
-msgstr "Sola Hizala"
-
-#: Layouts/Partials/AlignItemsPanel.vala:53
-msgid "Align Center"
-msgstr "Ortaya Hizala"
-
-#: Layouts/Partials/AlignItemsPanel.vala:54
-msgid "Align Right"
-msgstr "Sağa Hizala"
-
-#: Layouts/Partials/AlignItemsPanel.vala:56
-msgid "Align Top"
-msgstr "Yukarı Hizala"
-
-#: Layouts/Partials/AlignItemsPanel.vala:57
-msgid "Align Middle"
-msgstr "Ortaya Hizala"
-
-#: Layouts/Partials/AlignItemsPanel.vala:58
-msgid "Align Bottom"
-msgstr "Aşağı Hizala"
-
-#: Layouts/Partials/Artboard.vala:144 Layouts/Partials/Artboard.vala:487
-#: Layouts/Partials/Layer.vala:139 Layouts/Partials/Layer.vala:687
-msgid "Lock Layer"
-msgstr "Katmanı Kilitle"
-
-#: Layouts/Partials/Artboard.vala:155 Layouts/Partials/Artboard.vala:529
-#: Layouts/Partials/Layer.vala:156 Layouts/Partials/Layer.vala:729
-msgid "Hide Layer"
-msgstr "Katmanı Gizle"
-
-#: Layouts/Partials/Artboard.vala:487 Layouts/Partials/Layer.vala:687
-msgid "Unlock Layer"
-msgstr "Katmanın Kilidini Aç"
-
-#: Layouts/Partials/Artboard.vala:529 Layouts/Partials/Layer.vala:729
-msgid "Show Layer"
-msgstr "Katmanı Göster"
-
-#: Layouts/Partials/BorderItem.vala:121
-msgid "Choose border color"
-msgstr "Kenar rengi seç"
-
-#: Layouts/Partials/BorderItem.vala:176 Layouts/Partials/FillItem.vala:178
-msgid "Pick color"
-msgstr "Renk seç"
-
-#: Layouts/Partials/BorderItem.vala:191
-msgid "Remove border"
-msgstr "Kenarı kaldır"
-
-#: Layouts/Partials/BorderItem.vala:275
-msgid "Show border"
-msgstr "Kenarı göster"
-
-#: Layouts/Partials/BorderItem.vala:279
-msgid "Hide border"
-msgstr "Kenarı gizle"
-
-#: Layouts/Partials/BorderRadiusPanel.vala:86
-msgid "Style"
-msgstr "Biçim"
-
-#: Layouts/Partials/BorderRadiusPanel.vala:103
-msgid "Border Radius"
-msgstr "Kenar Yarıçapı"
-
-#: Layouts/Partials/BorderRadiusPanel.vala:137
-msgid "Border radius options"
-msgstr "Kenar yarıçapı seçenekleri"
-
-#: Layouts/Partials/BorderRadiusPanel.vala:199
-msgid "Autoscale Corners"
-msgstr "Köşeleri Otomatik Ölçeklendir"
-
-#: Layouts/Partials/BorderRadiusPanel.vala:208
-msgid "Uniform Corners"
-msgstr "Tüm Köşeler Aynı Biçimde"
-
-#: Layouts/Partials/BordersPanel.vala:53
-msgid "Borders"
-msgstr "Kenarlar"
-
-#: Layouts/Partials/BordersPanel.vala:64
-msgid "Add border"
-msgstr "Kenar ekle"
-
-#: Layouts/Partials/FillItem.vala:114
-msgid "Choose fill color"
-msgstr "Dolgu rengi seç"
-
-#: Layouts/Partials/FillItem.vala:193
-msgid "Remove fill color"
-msgstr "Dolgu rengini kaldır"
-
-#: Layouts/Partials/FillItem.vala:277
-msgid "Show fill color"
-msgstr "Dolgu rengini göster"
-
-#: Layouts/Partials/FillItem.vala:281
-msgid "Hide fill color"
-msgstr "Dolgu rengini gizle"
-
-#: Layouts/Partials/FillsPanel.vala:54
-msgid "Fills"
-msgstr "Dolgular"
-
-#: Layouts/Partials/FillsPanel.vala:65
-msgid "Add fill color"
-msgstr "Dolgu rengi ekle"
-
-#: Layouts/Partials/TransformPanel.vala:96
-msgid "X"
-msgstr "X"
-
-#: Layouts/Partials/TransformPanel.vala:96
-msgid "Horizontal position"
-msgstr "Yatay konum"
-
-#: Layouts/Partials/TransformPanel.vala:98
-msgid "Y"
-msgstr "Y"
-
-#: Layouts/Partials/TransformPanel.vala:98
-msgid "Vertical position"
-msgstr "Dikey konum"
-
-#: Layouts/Partials/TransformPanel.vala:100
-msgid "W"
-msgstr "G"
-
-#: Layouts/Partials/TransformPanel.vala:100
-msgid "Width"
-msgstr "Genişlik"
-
-#: Layouts/Partials/TransformPanel.vala:102
-msgid "H"
-msgstr "Y"
-
-#: Layouts/Partials/TransformPanel.vala:102
-msgid "Height"
-msgstr "Yükseklik"
-
-#: Layouts/Partials/TransformPanel.vala:107
-msgid "Lock Ratio"
-msgstr "Oranı Sabitle"
-
-#: Layouts/Partials/TransformPanel.vala:114
-msgid "R"
-msgstr "D"
-
-#: Layouts/Partials/TransformPanel.vala:114
-msgid "Rotation degrees"
-msgstr "Dönme derecesi"
-
-#: Layouts/Partials/TransformPanel.vala:126
-msgid "Flip Horizontally"
-msgstr "Yatay Olarak Çevir"
-
-#: Layouts/Partials/TransformPanel.vala:137
-msgid "Flip Vertically"
-msgstr "Dikey Olarak Çevir"
-
-#: Layouts/Partials/TransformPanel.vala:165
-msgid "Position"
-msgstr "Konum"
-
-#: Layouts/Partials/TransformPanel.vala:169
-msgid "Size"
-msgstr "Boyut"
-
-#: Layouts/Partials/TransformPanel.vala:178
-msgid "Opacity"
-msgstr "Saydamlık"
-
-#: Layouts/RightSideBar.vala:111
-msgid "Search Layer"
-msgstr "Katman Ara"
-
-#: Lib/Managers/ExportManager.vala:192 Lib/Managers/ExportManager.vala:219
-msgid "Generating preview, please wait…"
-msgstr "Önizleme oluşturuluyor, lütfen bekleyin…"
-
-#: Lib/Managers/ExportManager.vala:313
-#, c-format
-msgid "Untitled %i"
-msgstr "İsimsiz %i"
-
-#: Lib/Managers/ExportManager.vala:484
-msgid "Exporting images…"
-msgstr "Resimler dışarı aktarılıyor…"
-
-#: Partials/ExportWidget.vala:117
-#, c-format
-msgid "%i × %i px · %s"
-msgstr "%i × %i px · %s"
-
-#: Partials/ExportWidget.vala:124
-msgid "Fetching image size…"
-msgstr "Resim boyutu getiriliyor…"
-
-#: Partials/ZoomButton.vala:49
-msgid "Zoom Out"
-msgstr "Küçült"
-
-#: Partials/ZoomButton.vala:55
-msgid "Reset Zoom"
-msgstr "Yakınlaştırmayı Sıfırla"
-
-#: Partials/ZoomButton.vala:62
-msgid "Zoom In"
-msgstr "Büyüt"
-
-#: Partials/ZoomButton.vala:68
-msgid "Zoom"
-msgstr "Yakınlaştırma"
-
-#: Services/ActionManager.vala:217
-msgid "No recently opened file available!"
-msgstr "Yakın zamanda açılmış bir dosya yok!"
-
-#: Services/ActionManager.vala:236
-msgid "No second most recently opened file available!"
-msgstr "Yakın zamanda açılmış ikinci bir dosya yok!"
-
-#: Services/ActionManager.vala:255
-msgid "No third most recently opened file available!"
-msgstr "Yakın zamanda açılmış üçüncü bir dosya yok!"
-
-#: Services/ActionManager.vala:293
-msgid "Nothing selected to export!"
-msgstr "Dışarı aktarılacak bir şey seçilmedi!"
-
-#: Services/ActionManager.vala:302
-msgid "Export of Artboards currently unavailable…sorry 😑️"
-msgstr "Çalışma yüzeylerini dışarı aktarmak henüz mümkün değil…üzgünüm 😑️"
-
-#: Services/ActionManager.vala:373
-msgid "Choose image file"
-msgstr "Resim dosyası seç"
-
-#: Services/ActionManager.vala:373
-msgid "Select"
-msgstr "Seç"
-
-#: Services/ActionManager.vala:373
-msgid "Close"
-msgstr "Kapat"
-
-#: Services/ActionManager.vala:442
-#, c-format
-msgid "Error! .%s files are not supported!"
-msgstr "Hata! .%s dosyaları desteklenmemektedir!"
-
-#: Window.vala:121
-msgid "Are you sure you want to quit?"
-msgstr "Çıkış yapmak istediğinizden emin misiniz?"
-
-#: Window.vala:122
-msgid "All unsaved data will be lost and impossible to recover."
-msgstr ""
-"Kaydedilmemiş tüm veriler kurtarması mümkün olmayacak şekilde "
-"kaybolacaktır."
-
-#: Window.vala:124
-msgid "Quit without saving!"
-msgstr "Kaydetmeden çık!"
-
-#: Window.vala:125
-msgid "Save file"
-msgstr "Dosyayı kaydet"
diff --git a/po/ts.po b/po/ts.po
deleted file mode 100644
index 7d7bf5d53..000000000
--- a/po/ts.po
+++ /dev/null
@@ -1,4 +0,0 @@
-msgid ""
-msgstr ""
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
diff --git a/po/tt.po b/po/tt.po
deleted file mode 100644
index 7d7bf5d53..000000000
--- a/po/tt.po
+++ /dev/null
@@ -1,4 +0,0 @@
-msgid ""
-msgstr ""
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
diff --git a/po/tw.po b/po/tw.po
deleted file mode 100644
index 7d7bf5d53..000000000
--- a/po/tw.po
+++ /dev/null
@@ -1,4 +0,0 @@
-msgid ""
-msgstr ""
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
diff --git a/po/ty.po b/po/ty.po
deleted file mode 100644
index 7d7bf5d53..000000000
--- a/po/ty.po
+++ /dev/null
@@ -1,4 +0,0 @@
-msgid ""
-msgstr ""
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
diff --git a/po/ug.po b/po/ug.po
deleted file mode 100644
index 7d7bf5d53..000000000
--- a/po/ug.po
+++ /dev/null
@@ -1,4 +0,0 @@
-msgid ""
-msgstr ""
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
diff --git a/po/uk.po b/po/uk.po
deleted file mode 100644
index 6188ef853..000000000
--- a/po/uk.po
+++ /dev/null
@@ -1,5 +0,0 @@
-msgid ""
-msgstr ""
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
-"Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n"
diff --git a/po/ur.po b/po/ur.po
deleted file mode 100644
index 7d7bf5d53..000000000
--- a/po/ur.po
+++ /dev/null
@@ -1,4 +0,0 @@
-msgid ""
-msgstr ""
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
diff --git a/po/uz.po b/po/uz.po
deleted file mode 100644
index 7d7bf5d53..000000000
--- a/po/uz.po
+++ /dev/null
@@ -1,4 +0,0 @@
-msgid ""
-msgstr ""
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
diff --git a/po/ve.po b/po/ve.po
deleted file mode 100644
index 7d7bf5d53..000000000
--- a/po/ve.po
+++ /dev/null
@@ -1,4 +0,0 @@
-msgid ""
-msgstr ""
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
diff --git a/po/vi.po b/po/vi.po
deleted file mode 100644
index 2f3f844f3..000000000
--- a/po/vi.po
+++ /dev/null
@@ -1,5 +0,0 @@
-msgid ""
-msgstr ""
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
-"Plural-Forms: nplurals=2; plural=n == 1 ? 0 : 1;\n"
diff --git a/po/vo.po b/po/vo.po
deleted file mode 100644
index 7d7bf5d53..000000000
--- a/po/vo.po
+++ /dev/null
@@ -1,4 +0,0 @@
-msgid ""
-msgstr ""
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
diff --git a/po/wa.po b/po/wa.po
deleted file mode 100644
index 7d7bf5d53..000000000
--- a/po/wa.po
+++ /dev/null
@@ -1,4 +0,0 @@
-msgid ""
-msgstr ""
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
diff --git a/po/wo.po b/po/wo.po
deleted file mode 100644
index 7d7bf5d53..000000000
--- a/po/wo.po
+++ /dev/null
@@ -1,4 +0,0 @@
-msgid ""
-msgstr ""
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
diff --git a/po/xh.po b/po/xh.po
deleted file mode 100644
index 7d7bf5d53..000000000
--- a/po/xh.po
+++ /dev/null
@@ -1,4 +0,0 @@
-msgid ""
-msgstr ""
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
diff --git a/po/yi.po b/po/yi.po
deleted file mode 100644
index 7d7bf5d53..000000000
--- a/po/yi.po
+++ /dev/null
@@ -1,4 +0,0 @@
-msgid ""
-msgstr ""
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
diff --git a/po/yo.po b/po/yo.po
deleted file mode 100644
index 7d7bf5d53..000000000
--- a/po/yo.po
+++ /dev/null
@@ -1,4 +0,0 @@
-msgid ""
-msgstr ""
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
diff --git a/po/za.po b/po/za.po
deleted file mode 100644
index 7d7bf5d53..000000000
--- a/po/za.po
+++ /dev/null
@@ -1,4 +0,0 @@
-msgid ""
-msgstr ""
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
diff --git a/po/zh.po b/po/zh.po
deleted file mode 100644
index 7d7bf5d53..000000000
--- a/po/zh.po
+++ /dev/null
@@ -1,4 +0,0 @@
-msgid ""
-msgstr ""
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
diff --git a/po/zh_CN.po b/po/zh_CN.po
deleted file mode 100644
index cb1a3728a..000000000
--- a/po/zh_CN.po
+++ /dev/null
@@ -1,666 +0,0 @@
-msgid ""
-msgstr ""
-"Project-Id-Version: Akira 0.0.11 alpha\n"
-"POT-Creation-Date: 2020-08-05 20:25+0800\n"
-"PO-Revision-Date: \n"
-"Last-Translator: WhiredPlanck \n"
-"Language-Team: \n"
-"Language: zh_CN\n"
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
-"Content-Transfer-Encoding: 8bit\n"
-"X-Generator: Poedit 2.3.1\n"
-"X-Poedit-Basepath: ../src\n"
-"Plural-Forms: nplurals=1; plural=0;\n"
-"X-Poedit-SearchPath-0: .\n"
-
-#: Dialogs/ExportDialog.vala:151
-msgid "Export to:"
-msgstr "导出到:"
-
-#: Dialogs/ExportDialog.vala:157
-msgid "Select Folder"
-msgstr "选择文件夹"
-
-#: Dialogs/ExportDialog.vala:166
-msgid "Format:"
-msgstr "格式:"
-
-#: Dialogs/ExportDialog.vala:180
-msgid "Quality:"
-msgstr "质量:"
-
-#: Dialogs/ExportDialog.vala:192
-msgid "Compression:"
-msgstr "压缩等级:"
-
-#: Dialogs/ExportDialog.vala:206
-msgid "Transparency:"
-msgstr "透明度:"
-
-#: Dialogs/ExportDialog.vala:219
-msgid "Scale:"
-msgstr "比例:"
-
-#: Dialogs/ExportDialog.vala:243 FileFormat/FileManager.vala:49
-#: FileFormat/FileManager.vala:105
-msgid "Cancel"
-msgstr "取消"
-
-#: Dialogs/ExportDialog.vala:250 Dialogs/ShortcutsDialog.vala:63
-#: Layouts/HeaderBar.vala:113
-msgid "Export"
-msgstr "导出"
-
-#: Dialogs/ReleaseDialog.vala:47 Dialogs/SettingsDialog.vala:217
-msgid ""
-"WARNING!\n"
-"Akira is still under development and not ready for production. Missing "
-"features, random bugs, and black holes opening in your kitchen are to be "
-"expected."
-msgstr ""
-"** 警告!**\n"
-"Akira 仍在开发当中,尚未能正式成为生产工具。请准备好忍受功能上的缺失、随"
-"机出现的 Bug,以及吞噬劳作成果的“黑洞”。"
-
-#: Dialogs/ReleaseDialog.vala:100 Dialogs/SettingsDialog.vala:249
-msgid "Make a Donation"
-msgstr "捐献我们"
-
-#: Dialogs/ReleaseDialog.vala:109 Dialogs/SettingsDialog.vala:258
-msgid "Suggest Translations"
-msgstr "提供翻译建议"
-
-#: Dialogs/ReleaseDialog.vala:118 Dialogs/SettingsDialog.vala:267
-msgid "Report a Problem"
-msgstr "向我们报告问题"
-
-#: Dialogs/SettingsDialog.vala:40
-msgid "Preferences"
-msgstr "偏好设置"
-
-#: Dialogs/SettingsDialog.vala:50 Dialogs/SettingsDialog.vala:73
-#: Dialogs/ShortcutsDialog.vala:45
-msgid "General"
-msgstr "常规"
-
-#: Dialogs/SettingsDialog.vala:51 Dialogs/SettingsDialog.vala:86
-msgid "Interface"
-msgstr "界面"
-
-#: Dialogs/SettingsDialog.vala:52 Layouts/HeaderBar.vala:281
-msgid "Shapes"
-msgstr "形状"
-
-#: Dialogs/SettingsDialog.vala:53
-msgid "About"
-msgstr "关于"
-
-#: Dialogs/SettingsDialog.vala:74
-msgid "Auto Reopen Latest File:"
-msgstr "自动重新打开最新(近)文件:"
-
-#: Dialogs/SettingsDialog.vala:88
-msgid "Use Dark Theme:"
-msgstr "使用暗色主题:"
-
-#: Dialogs/SettingsDialog.vala:92
-msgid "Invert Panels Order:"
-msgstr "反转面板顺序:"
-
-#: Dialogs/SettingsDialog.vala:96
-msgid "Restart application to apply this change."
-msgstr "重启应用程序以应用更改。"
-
-#: Dialogs/SettingsDialog.vala:100
-msgid "ToolBar Style"
-msgstr "工具栏样式"
-
-#: Dialogs/SettingsDialog.vala:102
-msgid "Show Button Labels:"
-msgstr "显示按钮标签:"
-
-#: Dialogs/SettingsDialog.vala:106
-msgid "Use Symbolic Icons:"
-msgstr "使用符号图标:"
-
-#: Dialogs/SettingsDialog.vala:129
-msgid "Default Colors"
-msgstr "默认颜色"
-
-#: Dialogs/SettingsDialog.vala:131
-msgid "Define the default style used when creating a new shape."
-msgstr "定义创建新形状时使用的默认样式。"
-
-#: Dialogs/SettingsDialog.vala:136
-msgid "Fill Color:"
-msgstr "填充颜色:"
-
-#: Dialogs/SettingsDialog.vala:157
-msgid "Enable Border Style:"
-msgstr "启用边框样式:"
-
-#: Dialogs/SettingsDialog.vala:160
-msgid "Border Color:"
-msgstr "边框颜色:"
-
-#: Dialogs/SettingsDialog.vala:181
-msgid "Border Width:"
-msgstr "边框宽度:"
-
-#: Dialogs/SettingsDialog.vala:209
-msgid "The Linux Design Tool"
-msgstr "Linux 设计工具"
-
-#: Dialogs/SettingsDialog.vala:226
-msgid "Thanks to our awesome supporters!"
-msgstr "感谢我们出色的支持者!"
-
-#: Dialogs/SettingsDialog.vala:231
-msgid "View the list of supporters"
-msgstr "查看支持者名单"
-
-#: Dialogs/ShortcutsDialog.vala:46
-msgid "New window:"
-msgstr "新建窗口:"
-
-#: Dialogs/ShortcutsDialog.vala:48
-msgid "Preferences:"
-msgstr "偏好设置:"
-
-#: Dialogs/ShortcutsDialog.vala:50
-msgid "Quit:"
-msgstr "退出:"
-
-#: Dialogs/ShortcutsDialog.vala:52
-msgid "Presentation mode:"
-msgstr "演示模式:"
-
-#: Dialogs/ShortcutsDialog.vala:55
-msgid "File"
-msgstr "文件"
-
-#: Dialogs/ShortcutsDialog.vala:56
-msgid "Open:"
-msgstr "打开:"
-
-#: Dialogs/ShortcutsDialog.vala:58
-msgid "Save:"
-msgstr "保存:"
-
-#: Dialogs/ShortcutsDialog.vala:60
-msgid "Save as:"
-msgstr "另存为:"
-
-#: Dialogs/ShortcutsDialog.vala:64
-msgid "Export artboards:"
-msgstr "导出画板:"
-
-#: Dialogs/ShortcutsDialog.vala:66
-msgid "Export selection:"
-msgstr "导出所选:"
-
-#: Dialogs/ShortcutsDialog.vala:68
-msgid "Highlight area to export:"
-msgstr "高亮要导出的区域:"
-
-#: Dialogs/ShortcutsDialog.vala:77
-msgid "Canvas"
-msgstr "帆布"
-
-#: Dialogs/ShortcutsDialog.vala:78
-msgid "Zoom in:"
-msgstr "放大:"
-
-#: Dialogs/ShortcutsDialog.vala:80
-msgid "Zoom out:"
-msgstr "缩小:"
-
-#: Dialogs/ShortcutsDialog.vala:82
-msgid "Zoom reset:"
-msgstr "重置缩放:"
-
-#: Dialogs/ShortcutsDialog.vala:85
-msgid "Item creation"
-msgstr "项目创建"
-
-#: Dialogs/ShortcutsDialog.vala:86
-msgid "Artboard:"
-msgstr "画板:"
-
-#: Dialogs/ShortcutsDialog.vala:88
-msgid "Rectangle:"
-msgstr "矩形:"
-
-#: Dialogs/ShortcutsDialog.vala:90
-msgid "Ellipse:"
-msgstr "椭圆:"
-
-#: Dialogs/ShortcutsDialog.vala:92
-msgid "Text:"
-msgstr "文本:"
-
-#: Dialogs/ShortcutsDialog.vala:94
-msgid "Image:"
-msgstr "图像:"
-
-#: Dialogs/ShortcutsDialog.vala:97 Layouts/Partials/TransformPanel.vala:174
-msgid "Transform"
-msgstr "变换"
-
-#: Dialogs/ShortcutsDialog.vala:98
-msgid "Raise selection:"
-msgstr "上移所选:"
-
-#: Dialogs/ShortcutsDialog.vala:100
-msgid "Lower selection:"
-msgstr "下移所选:"
-
-#: Dialogs/ShortcutsDialog.vala:102
-msgid "Raise selection to top:"
-msgstr "将所选上移到顶层:"
-
-#: Dialogs/ShortcutsDialog.vala:104
-msgid "Lower selection to bottom:"
-msgstr "将所选下移到底层:"
-
-#: Dialogs/ShortcutsDialog.vala:106
-msgid "Flip horizontally:"
-msgstr "水平翻转:"
-
-#: Dialogs/ShortcutsDialog.vala:108
-msgid "Flip vertically:"
-msgstr "垂直翻转:"
-
-#: FileFormat/FileManager.vala:46
-msgid "Save Akira file"
-msgstr "保存 Akira 文件"
-
-#: FileFormat/FileManager.vala:48 Layouts/HeaderBar.vala:191
-msgid "Save"
-msgstr "保存"
-
-#: FileFormat/FileManager.vala:71
-msgid "Akira files"
-msgstr "Akira 文件"
-
-#: FileFormat/FileManager.vala:76
-msgid "All files"
-msgstr "所有文件"
-
-#: FileFormat/FileManager.vala:103
-msgid "Open Akira file"
-msgstr "打开 Akira 文件"
-
-#: FileFormat/FileManager.vala:105 Layouts/HeaderBar.vala:171
-msgid "Open"
-msgstr "打开"
-
-#: Layouts/HeaderBar.vala:69 Lib/Managers/ExportManager.vala:296
-msgid "Untitled"
-msgstr "无标题"
-
-#: Layouts/HeaderBar.vala:71
-msgid "Menu"
-msgstr "菜单"
-
-#: Layouts/HeaderBar.vala:75
-msgid "Insert"
-msgstr "插入"
-
-#: Layouts/HeaderBar.vala:82
-msgid "Group"
-msgstr "合并"
-
-#: Layouts/HeaderBar.vala:84
-msgid "Ungroup"
-msgstr "取消合并"
-
-#: Layouts/HeaderBar.vala:87
-msgid "Up"
-msgstr "上移一层"
-
-#: Layouts/HeaderBar.vala:92
-msgid "Down"
-msgstr "下移一层"
-
-#: Layouts/HeaderBar.vala:97
-msgid "Top"
-msgstr "置于顶层"
-
-#: Layouts/HeaderBar.vala:102
-msgid "Bottom"
-msgstr "置于底层"
-
-#: Layouts/HeaderBar.vala:108
-msgid "Settings"
-msgstr "设置"
-
-#: Layouts/HeaderBar.vala:119
-msgid "Difference"
-msgstr "差异"
-
-#: Layouts/HeaderBar.vala:121
-msgid "Exclusion"
-msgstr "排除"
-
-#: Layouts/HeaderBar.vala:123
-msgid "Intersect"
-msgstr "交集"
-
-#: Layouts/HeaderBar.vala:125
-msgid "Union"
-msgstr "并集"
-
-#: Layouts/HeaderBar.vala:162
-msgid "New Window"
-msgstr "新窗口"
-
-#: Layouts/HeaderBar.vala:183
-msgid "Open Recent"
-msgstr "打开最近文件"
-
-#: Layouts/HeaderBar.vala:196
-msgid "Save As"
-msgstr "另存为"
-
-#: Layouts/HeaderBar.vala:205
-msgid "Quit"
-msgstr "退出"
-
-#: Layouts/HeaderBar.vala:238
-msgid "Artboard"
-msgstr "画板"
-
-#: Layouts/HeaderBar.vala:255
-msgid "Add Items"
-msgstr "添加项目"
-
-#: Layouts/HeaderBar.vala:263
-msgid "Rectangle"
-msgstr "矩形"
-
-#: Layouts/HeaderBar.vala:269
-msgid "Ellipse"
-msgstr "椭圆"
-
-#: Layouts/HeaderBar.vala:287
-msgid "Vector"
-msgstr "矢量"
-
-#: Layouts/HeaderBar.vala:289
-msgid "Pencil"
-msgstr "铅笔"
-
-#: Layouts/HeaderBar.vala:292
-msgid "Text"
-msgstr "文本"
-
-#: Layouts/HeaderBar.vala:298
-msgid "Image"
-msgstr "图像"
-
-#: Layouts/HeaderBar.vala:331
-msgid "Export Current Selection"
-msgstr "导出当前所选"
-
-#: Layouts/HeaderBar.vala:337
-msgid "Export Artboards"
-msgstr "导出画板"
-
-#: Layouts/HeaderBar.vala:346
-msgid "Highlight Area to Export"
-msgstr "截取要导出的区域"
-
-#: Layouts/HeaderBar.vala:394
-msgid "Main Menu"
-msgstr "主菜单"
-
-#: Layouts/HeaderBar.vala:471 Services/ActionManager.vala:215
-#: Services/ActionManager.vala:234 Services/ActionManager.vala:253
-#, c-format
-msgid "Unable to open file at '%s'"
-msgstr "无法在 '%s' 打开文件"
-
-#: Layouts/MainCanvas.vala:52
-#, fuzzy
-msgid "Button was pressed!"
-msgstr "按钮被按下!"
-
-#: Layouts/MainCanvas.vala:160
-msgid "Export completed!"
-msgstr "导出完毕!"
-
-#: Layouts/Partials/AlignItemsPanel.vala:48
-msgid "Distribute Horizontally"
-msgstr "水平分布"
-
-#: Layouts/Partials/AlignItemsPanel.vala:50
-msgid "Distribute Vertically"
-msgstr "垂直分布"
-
-#: Layouts/Partials/AlignItemsPanel.vala:52
-msgid "Align Left"
-msgstr "左对齐"
-
-#: Layouts/Partials/AlignItemsPanel.vala:53
-msgid "Align Center"
-msgstr "居中对齐"
-
-#: Layouts/Partials/AlignItemsPanel.vala:54
-msgid "Align Right"
-msgstr "右对齐"
-
-#: Layouts/Partials/AlignItemsPanel.vala:56
-msgid "Align Top"
-msgstr "顶端对齐"
-
-#: Layouts/Partials/AlignItemsPanel.vala:57
-msgid "Align Middle"
-msgstr "中间对齐"
-
-#: Layouts/Partials/AlignItemsPanel.vala:58
-msgid "Align Bottom"
-msgstr "底端对齐"
-
-#: Layouts/Partials/Artboard.vala:144 Layouts/Partials/Layer.vala:139
-#: Layouts/Partials/Layer.vala:686
-msgid "Lock Layer"
-msgstr "锁定图层"
-
-#: Layouts/Partials/Artboard.vala:155 Layouts/Partials/Layer.vala:156
-#: Layouts/Partials/Layer.vala:727
-msgid "Hide Layer"
-msgstr "隐藏图层"
-
-#: Layouts/Partials/BorderRadiusPanel.vala:86
-msgid "Style"
-msgstr "样式"
-
-#: Layouts/Partials/BorderRadiusPanel.vala:103
-msgid "Border Radius"
-msgstr "边框半径"
-
-#: Layouts/Partials/BorderRadiusPanel.vala:198
-#, fuzzy
-msgid "Autoscale Corners"
-msgstr "自动最佳化圆角比例"
-
-#: Layouts/Partials/BorderRadiusPanel.vala:207
-msgid "Uniform Corners"
-msgstr "统一圆角半径"
-
-#: Layouts/Partials/BordersPanel.vala:53
-msgid "Borders"
-msgstr "边框"
-
-#: Layouts/Partials/FillsPanel.vala:54
-msgid "Fills"
-msgstr "填充"
-
-#: Layouts/Partials/Layer.vala:686
-msgid "Unlock Layer"
-msgstr "解锁图层"
-
-#: Layouts/Partials/Layer.vala:727
-msgid "Show Layer"
-msgstr "显示图层"
-
-#: Layouts/Partials/TransformPanel.vala:96
-msgid "X"
-msgstr "X"
-
-#: Layouts/Partials/TransformPanel.vala:96
-msgid "Horizontal position"
-msgstr "水平位置"
-
-#: Layouts/Partials/TransformPanel.vala:98
-msgid "Y"
-msgstr "Y"
-
-#: Layouts/Partials/TransformPanel.vala:98
-msgid "Vertical position"
-msgstr "垂直位置"
-
-#: Layouts/Partials/TransformPanel.vala:100
-msgid "W"
-msgstr "W"
-
-#: Layouts/Partials/TransformPanel.vala:100
-msgid "Width"
-msgstr "宽度"
-
-#: Layouts/Partials/TransformPanel.vala:102
-msgid "H"
-msgstr "H"
-
-#: Layouts/Partials/TransformPanel.vala:102
-msgid "Height"
-msgstr "高度"
-
-#: Layouts/Partials/TransformPanel.vala:107
-msgid "Lock Ratio"
-msgstr "锁定高宽比"
-
-#: Layouts/Partials/TransformPanel.vala:114
-msgid "R"
-msgstr "R"
-
-#: Layouts/Partials/TransformPanel.vala:114
-msgid "Rotation degrees"
-msgstr "旋转角度"
-
-#: Layouts/Partials/TransformPanel.vala:126
-msgid "Flip Horizontally"
-msgstr "水平翻转"
-
-#: Layouts/Partials/TransformPanel.vala:137
-msgid "Flip Vertically"
-msgstr "垂直翻转"
-
-#: Layouts/Partials/TransformPanel.vala:165
-msgid "Position"
-msgstr "位置"
-
-#: Layouts/Partials/TransformPanel.vala:169
-msgid "Size"
-msgstr "大小"
-
-#: Layouts/Partials/TransformPanel.vala:178
-msgid "Opacity"
-msgstr "不透明度"
-
-#: Layouts/RightSideBar.vala:111
-msgid "Search Layer"
-msgstr "搜索图层"
-
-#: Lib/Managers/ExportManager.vala:192 Lib/Managers/ExportManager.vala:219
-msgid "Generating preview, please wait…"
-msgstr "生成预览中,请稍候…"
-
-#: Lib/Managers/ExportManager.vala:313
-#, c-format
-msgid "Untitled %i"
-msgstr "无标题 %i"
-
-#: Lib/Managers/ExportManager.vala:484
-msgid "Exporting images…"
-msgstr "导出图像…"
-
-#: Partials/ExportWidget.vala:117
-#, c-format
-msgid "%i × %i px · %s"
-msgstr "%i × %i px · %s"
-
-#: Partials/ExportWidget.vala:124
-msgid "Fetching image size…"
-msgstr "撷取图片大小…"
-
-#: Partials/ZoomButton.vala:49
-msgid "Zoom Out"
-msgstr "缩小"
-
-#: Partials/ZoomButton.vala:55
-msgid "Reset Zoom"
-msgstr "重置缩放"
-
-#: Partials/ZoomButton.vala:62
-msgid "Zoom In"
-msgstr "放大"
-
-#: Partials/ZoomButton.vala:68
-msgid "Zoom"
-msgstr "缩放"
-
-#: Services/ActionManager.vala:208
-msgid "No recently opened file available!"
-msgstr "没有最近打开的文件!"
-
-#: Services/ActionManager.vala:227
-msgid "No second most recently opened file available!"
-msgstr "没有第二个最近打开的文件!"
-
-#: Services/ActionManager.vala:246
-msgid "No third most recently opened file available!"
-msgstr "没有第三个最近打开的文件!"
-
-#: Services/ActionManager.vala:284
-msgid "Nothing selected to export!"
-msgstr "没有选择要导出的内容!"
-
-#: Services/ActionManager.vala:293
-msgid "Export of Artboards currently unavailable…sorry 😑️"
-msgstr "目前无法导出画板…对不起 😑️"
-
-#: Services/ActionManager.vala:360
-msgid "Choose image file"
-msgstr "选择图像文件"
-
-#: Services/ActionManager.vala:360
-msgid "Select"
-msgstr "选择"
-
-#: Services/ActionManager.vala:360
-msgid "Close"
-msgstr "关闭"
-
-#: Services/ActionManager.vala:429
-#, c-format
-msgid "Error! .%s files are not supported!"
-msgstr "错误!不支持 .%s 文件!"
-
-#: Window.vala:119
-msgid "Are you sure you want to quit?"
-msgstr "确定要退出吗?"
-
-#: Window.vala:120
-msgid "All unsaved data will be lost and impossible to recover."
-msgstr "所有未保存的数据将丢失,并且无法恢复。"
-
-#: Window.vala:122
-msgid "Quit without saving!"
-msgstr "不保存并退出!"
-
-#: Window.vala:123
-msgid "Save file"
-msgstr "保存文件"
diff --git a/po/zh_HK.po b/po/zh_HK.po
deleted file mode 100644
index 7d7bf5d53..000000000
--- a/po/zh_HK.po
+++ /dev/null
@@ -1,4 +0,0 @@
-msgid ""
-msgstr ""
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
diff --git a/po/zh_TW.po b/po/zh_TW.po
deleted file mode 100644
index 7d7bf5d53..000000000
--- a/po/zh_TW.po
+++ /dev/null
@@ -1,4 +0,0 @@
-msgid ""
-msgstr ""
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
diff --git a/po/zu.po b/po/zu.po
deleted file mode 100644
index 7d7bf5d53..000000000
--- a/po/zu.po
+++ /dev/null
@@ -1,4 +0,0 @@
-msgid ""
-msgstr ""
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
diff --git a/src/Application.vala b/src/Application.vala
deleted file mode 100644
index e02e2bec8..000000000
--- a/src/Application.vala
+++ /dev/null
@@ -1,178 +0,0 @@
-/*
-* Copyright (c) 2019-2020 Alecaddd (https://alecaddd.com)
-*
-* This file is part of Akira.
-*
-* Akira 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.
-
-* Akira 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 Akira. If not, see .
-*
-* Authored by: Alessandro "Alecaddd" Castellani
-*/
-
-namespace Akira {
- public Akira.Services.Settings settings;
-}
-
-public class Akira.Application : Gtk.Application {
- public GLib.List windows;
-
- construct {
- flags |= ApplicationFlags.HANDLES_OPEN;
-
- settings = new Akira.Services.Settings ();
- windows = new GLib.List ();
-
- application_id = Constants.APP_ID;
- }
-
- public override void open (File[] files, string hint) {
- // Loop through all selected files.
- foreach (var file in files) {
- if (is_file_opened (file)) {
- // Present active window with currently opened file.
- // We don't allow opening the same file on multiple windows.
- var window = get_window_from_file (file);
- window.show_app ();
- continue;
- }
-
- // If the current window is empty, load the file in this one.
- var current_window = active_window as Akira.Window;
- if (current_window != null && current_window.akira_file == null && !current_window.edited) {
- current_window.open_file (file);
- current_window.event_bus.file_saved (file.get_basename ());
- continue;
- }
-
- // The application was requested to open some files. Be sure to
- // initialize the theme in case it wasn't already running.
- init_theme ();
-
- // Open a new window.
- var window = new Akira.Window (this);
- this.add_window (window);
-
- window.open_file (file);
- window.show_app ();
- window.event_bus.file_saved (file.get_basename ());
- }
- }
-
- public Akira.Window? get_window_from_file (File file) {
- foreach (Akira.Window window in windows) {
- if (window.akira_file != null && window.akira_file.opened_file.get_path () == file.get_path ()) {
- return window;
- }
- }
-
- return null;
- }
-
- public bool is_file_opened (File file) {
- foreach (Akira.Window window in windows) {
- if (window.akira_file != null && window.akira_file.opened_file.get_path () == file.get_path ()) {
- return true;
- }
- }
-
- return false;
- }
-
- public void new_window () {
- new Akira.Window (this).present ();
- }
-
- public override void window_added (Gtk.Window window) {
- windows.append (window as Akira.Window);
- base.window_added (window);
- }
-
- public override void window_removed (Gtk.Window window) {
- windows.remove (window as Akira.Window);
- base.window_removed (window);
- }
-
- /**
- * Update the list of recently opened files in all the currently opened Windows.
- */
- public void update_recent_files_list () {
- foreach (Akira.Window window in windows) {
- window.event_bus.update_recent_files_list ();
- }
- }
-
- protected override void activate () {
- init_theme ();
-
- var window = new Akira.Window (this);
- this.add_window (window);
-
- if (settings.version != Constants.VERSION) {
- var dialog = new Akira.Dialogs.ReleaseDialog (window);
- dialog.show_all ();
- dialog.present ();
-
- // Update the settings so we don't show the same dialog again.
- settings.version = Constants.VERSION;
- }
-
- // Load the most recently opened/saved file.
- if (settings.open_quick) {
- window.action_manager.action_load_first ();
- }
- }
-
- private void init_theme () {
- // Interrupt if we have at least one existing window, meaning the theme
- // was previously initialized.
- if (windows.length () > 0) {
- return;
- }
-
- // Add the resource path to load custom icons.
- weak Gtk.IconTheme default_theme = Gtk.IconTheme.get_default ();
- default_theme.add_resource_path ("/com/github/akiraux/akira");
-
- // Load the custom CSS.
- var css_provider = new Gtk.CssProvider ();
- css_provider.load_from_resource ("/com/github/akiraux/akira/stylesheet.css");
- Gtk.StyleContext.add_provider_for_screen (
- Gdk.Screen.get_default (), css_provider, Gtk.STYLE_PROVIDER_PRIORITY_APPLICATION
- );
-
- // Force set the elementary OS style and icons for visual consistency.
- // In the future we might support other themes if doable.
- var gtk_settings = Gtk.Settings.get_default ();
- gtk_settings.set_property ("gtk-icon-theme-name", "elementary");
- gtk_settings.set_property ("gtk-theme-name", "io.elementary.stylesheet.blueberry");
-
- // Use the Granite API to listen for global dark style changes.
- var granite_settings = Granite.Settings.get_default ();
- if (settings.follow_system_theme) {
- // Follow the system themeing.
- gtk_settings.gtk_application_prefer_dark_theme =
- granite_settings.prefers_color_scheme == Granite.Settings.ColorScheme.DARK;
- } else {
- // Follow the user's settings.
- gtk_settings.gtk_application_prefer_dark_theme = settings.dark_theme;
- }
-
- // Listen for the changes in the theme's preferences.
- granite_settings.notify["prefers-color-scheme"].connect (() => {
- if (settings.follow_system_theme) {
- gtk_settings.gtk_application_prefer_dark_theme =
- granite_settings.prefers_color_scheme == Granite.Settings.ColorScheme.DARK;
- }
- });
- }
-}
diff --git a/src/Dialogs/ExportDialog.vala b/src/Dialogs/ExportDialog.vala
deleted file mode 100644
index 85f29f39f..000000000
--- a/src/Dialogs/ExportDialog.vala
+++ /dev/null
@@ -1,359 +0,0 @@
-/*
-* Copyright (c) 2020-2022 Alecaddd (https://alecaddd.com)
-*
-* This file is part of Akira.
-*
-* Akira 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.
-
-* Akira 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 Akira. If not, see .
-*
-* Authored by: Alessandro "Alecaddd" Castellani
-*/
-
-public class Akira.Dialogs.ExportDialog : Gtk.Dialog {
- public unowned Lib.ViewCanvas canvas { get; construct; }
- public unowned Lib.Managers.ExportManager manager { get; construct; }
-
- public GLib.ListStore list_store;
-
- private Gtk.FlowBox export_grid;
- private Gtk.Grid sidebar;
- public Gtk.FileChooserButton folder_button;
- public Gtk.Adjustment quality_adj;
- public Gtk.Scale quality_scale;
- public Gtk.Adjustment compression_adj;
- public Gtk.Scale compression_scale;
- public Gtk.ComboBoxText file_format;
- public Gtk.Label jpg_title;
- public Gtk.Label png_title;
- public Gtk.Label alpha_title;
- public Gtk.Switch alpha_switch;
-
- private Gtk.Button export_button;
-
- private Gtk.Overlay main_overlay;
- private Granite.Widgets.Toast notification;
- private Granite.Widgets.OverlayBar overlaybar;
-
- private GLib.Cancellable? preview_cancellable;
-
- public ExportDialog (Lib.ViewCanvas view_canvas, Lib.Managers.ExportManager export_manager) {
- Object (
- canvas: view_canvas,
- manager: export_manager,
- border_width: 0,
- deletable: true,
- resizable: true,
- modal: true
- );
- }
-
- construct {
- transient_for = canvas.window;
- use_header_bar = 1;
- default_width = settings.export_width;
- default_height = settings.export_height;
-
- var sidebar_header = new Gtk.Grid () {
- vexpand = true,
- height_request = 30
- };
- sidebar_header.get_style_context ().add_class ("sidebar-export-header");
-
- var main_header = new Gtk.Grid () {
- vexpand = true
- };
-
- var pane_header = new Gtk.Paned (Gtk.Orientation.HORIZONTAL);
- pane_header.pack1 (sidebar_header, false, false);
- pane_header.pack2 (main_header, false, false);
- pane_header.get_style_context ().add_class ("export-titlebar");
-
- // Hack to remove the default header area and replace it with
- // a custom widget.
- var header_area = get_header_bar ();
- header_area.destroy ();
- set_titlebar (pane_header);
-
- // Another hack to remove the bottom action area.
- var button = add_button ("OK", 3);
- var button_area = button.get_parent ();
- button_area.destroy ();
-
- sidebar = new Gtk.Grid ();
- sidebar.get_style_context ().add_class ("sidebar-export");
- build_export_sidebar ();
-
- main_overlay = new Gtk.Overlay ();
- notification = new Granite.Widgets.Toast ("");
- overlaybar = new Granite.Widgets.OverlayBar (main_overlay);
- overlaybar.active = true;
-
- var main = new Gtk.Grid () {
- expand = true
- };
-
- list_store = new GLib.ListStore (typeof (Akira.Models.ExportModel));
-
- export_grid = new Gtk.FlowBox () {
- activate_on_single_click = false,
- max_children_per_line = 1,
- selection_mode = Gtk.SelectionMode.NONE,
- column_spacing = 12,
- row_spacing = 12
- };
- export_grid.get_style_context ().add_class ("export-panel");
-
- export_grid.bind_model (list_store, model => {
- return new Widgets.ExportWidget (model as Akira.Models.ExportModel);
- });
-
- var scrolled = new Gtk.ScrolledWindow (null, null) {
- expand = true
- };
- scrolled.get_style_context ().add_class (Gtk.STYLE_CLASS_VIEW);
- scrolled.add (export_grid);
- main.add (scrolled);
-
- main_overlay.add (main);
- main_overlay.add_overlay (notification);
-
- var pane = new Gtk.Paned (Gtk.Orientation.HORIZONTAL);
- pane.pack1 (sidebar, false, false);
- pane.pack2 (main_overlay, true, false);
-
- var content_area = get_content_area ();
- content_area.border_width = 0;
- content_area.add (pane);
-
- pane.bind_property ("position", pane_header, "position");
-
- pane_header.notify["position"].connect (() => {
- pane_header.position = pane.position;
- });
-
- settings.bind ("export-paned", pane, "position", SettingsBindFlags.DEFAULT);
- // GTK issue: combobox need to be added to a parent and be visible before
- // we can use bind () to prevent a critical error.
- settings.bind ("export-format", file_format, "active_id",
- SettingsBindFlags.DEFAULT | GLib.SettingsBindFlags.GET_NO_CHANGES);
-
- manager.busy.connect (on_busy);
- manager.show_preview.connect (on_show_preview);
- manager.free.connect (on_free);
- manager.export_finished.connect (on_export_finished);
-
- canvas.window.event_bus.toggle_export_button.connect (on_toggle_export_button);
- }
-
- private void build_export_sidebar () {
- var grid = new Gtk.Grid () {
- expand = true,
- column_spacing = 12,
- margin_start = 12,
- margin_end = 12,
- margin_bottom = 12,
- row_spacing = 6
- };
-
- // Folder location.
- grid.attach (section_title (_("Export to:")), 0, 0, 1, 1);
-
- if (settings.export_folder == "") {
- settings.export_folder = Environment.get_user_special_dir (UserDirectory.PICTURES);
- }
-
- folder_button = new Gtk.FileChooserButton (_("Select Folder"), Gtk.FileChooserAction.SELECT_FOLDER);
- folder_button.set_current_folder (settings.export_folder);
- folder_button.hexpand = true;
- grid.attach (folder_button, 1, 0, 1, 1);
- folder_button.selection_changed.connect (() => {
- settings.export_folder = folder_button.get_filename ();
- });
-
- // File format.
- var format_title = section_title (_("Format:"));
- grid.attach (format_title, 0, 2, 1, 1);
-
- file_format = new Gtk.ComboBoxText ();
- file_format.append ("png", "PNG");
- file_format.append ("jpg", "JPG");
- file_format.changed.connect (update_format_ui);
- grid.attach (file_format, 1, 2, 1, 1);
- settings.changed["export-format"].connect (() => {
- if (preview_cancellable != null) {
- preview_cancellable.cancel ();
- }
-
- preview_cancellable = new GLib.Cancellable ();
- manager.generate_preview.begin (preview_cancellable);
- });
-
- // Quality spinbutton.
- jpg_title = section_title (_("Quality:"));
- grid.attach (jpg_title, 0, 3, 1, 1);
-
- quality_adj = new Gtk.Adjustment (100.0, 0, 100.0, 0, 0, 0);
- quality_scale = new Gtk.Scale (Gtk.Orientation.HORIZONTAL, quality_adj) {
- hexpand = true,
- draw_value = true,
- digits = 0
- };
- grid.attach (quality_scale, 1, 3, 1, 1);
- quality_scale.button_release_event.connect (() => {
- settings.export_quality = (int) quality_adj.value;
- return false;
- });
-
- // Compression spinbutton.
- png_title = section_title (_("Compression:"));
- grid.attach (png_title, 0, 4, 1, 1);
-
- compression_adj = new Gtk.Adjustment (0.0, 0, 9.0, 1, 0, 0);
- compression_scale = new Gtk.Scale (Gtk.Orientation.HORIZONTAL, compression_adj) {
- hexpand = true,
- draw_value = true,
- digits = 0
- };
- for (int i = 1; i <= 9; i++) {
- compression_scale.add_mark (i, Gtk.PositionType.BOTTOM, null);
- }
- grid.attach (compression_scale, 1, 4, 1, 1);
- compression_scale.button_release_event.connect (() => {
- settings.export_compression = (int) compression_adj.value;
- return false;
- });
-
- alpha_title = section_title (_("Transparency:"));
- grid.attach (alpha_title, 0, 5, 1, 1);
-
- alpha_switch = new Gtk.Switch () {
- valign = Gtk.Align.CENTER,
- halign = Gtk.Align.START
- };
- grid.attach (alpha_switch, 1, 5, 1, 1);
- settings.bind ("export-alpha", alpha_switch, "active",
- SettingsBindFlags.DEFAULT | SettingsBindFlags.GET_NO_CHANGES);
- settings.changed["export-alpha"].connect (() => {
- if (preview_cancellable != null) {
- preview_cancellable.cancel ();
- }
-
- preview_cancellable = new GLib.Cancellable ();
- manager.generate_preview.begin (preview_cancellable);
- });
-
- // Resolution.
- var size_title = section_title (_("Scale:"));
- grid.attach (size_title, 0, 6, 1, 1);
-
- var scale_button = new Granite.Widgets.ModeButton () {
- halign = Gtk.Align.FILL
- };
- scale_button.append_text ("0.5×");
- scale_button.append_text ("1×");
- scale_button.append_text ("2×");
- scale_button.append_text ("4×");
- scale_button.set_active (settings.export_scale);
- settings.bind ("export-scale", scale_button, "selected",
- SettingsBindFlags.DEFAULT | SettingsBindFlags.GET_NO_CHANGES);
- grid.attach (scale_button, 1, 6, 1, 1);
- settings.changed["export-scale"].connect (() => {
- if (preview_cancellable != null) {
- preview_cancellable.cancel ();
- }
-
- preview_cancellable = new GLib.Cancellable ();
- manager.generate_preview.begin (preview_cancellable);
- });
-
- // Buttons.
- var action_area = new Gtk.Grid () {
- column_spacing = 6,
- halign = Gtk.Align.END,
- valign = Gtk.Align.END,
- vexpand = true
- };
- grid.attach (action_area, 0, 7, 2, 1);
-
- var cancel_button = new Gtk.Button.with_label (_("Cancel")) {
- halign = Gtk.Align.START
- };
- action_area.add (cancel_button);
- cancel_button.clicked.connect (() => {
- close ();
- });
-
- export_button = new Gtk.Button.with_label (_("Export")) {
- halign = Gtk.Align.END
- };
- export_button.get_style_context ().add_class (Gtk.STYLE_CLASS_SUGGESTED_ACTION);
- action_area.add (export_button);
- export_button.clicked.connect (() => {
- manager.export_images.begin (list_store);
- });
-
- sidebar.add (grid);
- }
-
- public void update_format_ui () {
- jpg_title.visible = (file_format.active_id == "jpg");
- quality_scale.visible = (file_format.active_id == "jpg");
-
- png_title.visible = (file_format.active_id == "png");
- compression_scale.visible = (file_format.active_id == "png");
- alpha_title.visible = (file_format.active_id == "png");
- alpha_switch.visible = (file_format.active_id == "png");
- }
-
- public async void on_show_preview (Gee.HashMap pixbufs) {
- list_store.remove_all ();
- foreach (var entry in pixbufs.entries) {
- var node = entry.key == Lib.Items.Model.ORIGIN_ID ?
- null : canvas.items_manager.node_from_id (entry.key);
- var model = new Models.ExportModel (canvas, node, entry.value);
- list_store.append (model);
- }
- }
-
- private Gtk.Label section_title (string title) {
- var title_label = new Gtk.Label (title) {
- halign = Gtk.Align.END
- };
-
- return title_label;
- }
-
- private async void on_busy (string message) {
- overlaybar.label = message;
- overlaybar.visible = true;
- sidebar.@foreach ((child) => {
- child.sensitive = false;
- });
- }
-
- private async void on_free () {
- sidebar.@foreach ((child) => {
- child.sensitive = true;
- });
- overlaybar.visible = false;
- }
-
- public void on_export_finished (string message) {
- notification.title = message;
- notification.send_notification ();
- }
-
- private void on_toggle_export_button (bool sensitive) {
- export_button.sensitive = sensitive;
- }
-}
diff --git a/src/Dialogs/ReleaseDialog.vala b/src/Dialogs/ReleaseDialog.vala
deleted file mode 100644
index e5dfada93..000000000
--- a/src/Dialogs/ReleaseDialog.vala
+++ /dev/null
@@ -1,145 +0,0 @@
-/*
-* Copyright (c) 2020 Alecaddd (https://alecaddd.com)
-*
-* This file is part of Akira.
-*
-* Akira 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.
-
-* Akira 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 Akira. If not, see .
-*
-* Authored by: Alessandro "Alecaddd" Castellani
-*/
-
-public class Akira.Dialogs.ReleaseDialog : Gtk.Dialog {
- public weak Akira.Window window { get; construct; }
-
- public ReleaseDialog (Akira.Window window) {
- Object (
- window: window,
- border_width: 10,
- deletable: true,
- resizable: false,
- modal: true
- );
- }
-
- construct {
- transient_for = window;
- default_width = 624;
-
- var banner_grid = new Gtk.Grid ();
- banner_grid.get_style_context ().add_class ("banner");
- banner_grid.halign = Gtk.Align.CENTER;
- banner_grid.width_request = 600;
- banner_grid.height_request = 200;
- banner_grid.margin_bottom = 6;
-
- var disclaimer = new Gtk.Label (
- _("WARNING!\nAkira is still under development and not ready for production. Missing features, random bugs, and black holes opening in your kitchen are to be expected."
- )
- );
- disclaimer.justify = Gtk.Justification.CENTER;
- disclaimer.margin_top = disclaimer.margin_bottom = 6;
- disclaimer.margin_start = disclaimer.margin_end = 3;
- disclaimer.max_width_chars = 80;
- disclaimer.wrap = true;
-
- var warning_grid = new Gtk.Grid ();
- warning_grid.halign = Gtk.Align.CENTER;
- warning_grid.margin_bottom = 24;
- warning_grid.get_style_context ().add_class ("warning-message");
- warning_grid.add (disclaimer);
-
- var app_version = new Gtk.Label ("v" + Constants.VERSION + " - alpha");
- app_version.get_style_context ().add_class ("h2");
- app_version.selectable = true;
-
- var version_title = new Gtk.Label ("Performance improvements and Global colors library");
- version_title.get_style_context ().add_class ("h3");
-
- var version_date = new Gtk.Label ("Jul 20th, 2021");
- version_date.get_style_context ().add_class ("dim-label");
-
- var header_grid = new Gtk.Grid ();
- header_grid.halign = Gtk.Align.CENTER;
- header_grid.margin_bottom = 12;
- header_grid.attach (app_version, 0, 0);
- header_grid.attach (version_title, 0, 1);
- header_grid.attach (version_date, 0, 2);
-
- var scrolled = new Gtk.ScrolledWindow (null, null);
- scrolled.min_content_height = 200;
- scrolled.expand = true;
-
- var release_info = new Gtk.TextView ();
- release_info.buffer.text = "✓ Improved 'Modes' detection (insert, select, transform).\n✓ Fixed Artboard label issues on zoom.\n✓ Improved Pixel Grid detection and z-index stack with other items.\n✓ Implemented editable zoom value.\n✓ Fix application activation when opening a new file.\n✓ Fix sizing issue when dropping images into the Canvas.\n✓ Implemented Global colors library.\n✓ Italian translation.\n";
- release_info.pixels_below_lines = 3;
- release_info.border_width = 12;
- release_info.wrap_mode = Gtk.WrapMode.WORD;
- release_info.cursor_visible = false;
- release_info.editable = false;
- release_info.get_style_context ().add_class (Granite.STYLE_CLASS_TERMINAL);
-
- scrolled.add (release_info);
-
- // Button grid at the bottom of the dialog.
- var button_grid = new Gtk.ButtonBox (Gtk.Orientation.HORIZONTAL);
- button_grid.halign = Gtk.Align.CENTER;
- button_grid.spacing = 6;
- button_grid.margin_top = 12;
-
- var donate_button = new Gtk.Button.with_label (_("Make a Donation"));
- donate_button.clicked.connect (() => {
- try {
- AppInfo.launch_default_for_uri ("https://github.com/akiraux/Akira#-support", null);
- } catch (Error e) {
- warning (e.message);
- }
- });
-
- var translate_button = new Gtk.Button.with_label (_("Suggest Translations"));
- translate_button.clicked.connect (() => {
- try {
- AppInfo.launch_default_for_uri ("https://github.com/akiraux/Akira/issues", null);
- } catch (Error e) {
- warning (e.message);
- }
- });
-
- var bug_button = new Gtk.Button.with_label (_("Report a Problem"));
- bug_button.clicked.connect (() => {
- try {
- AppInfo.launch_default_for_uri ("https://github.com/akiraux/Akira/issues", null);
- } catch (Error e) {
- warning (e.message);
- }
- });
-
- button_grid.add (donate_button);
- button_grid.add (translate_button);
- button_grid.add (bug_button);
-
- var grid = new Gtk.Grid ();
- grid.column_spacing = 12;
- grid.hexpand = true;
-
- grid.attach (banner_grid, 0, 0);
- grid.attach (warning_grid, 0, 1);
- grid.attach (header_grid, 0, 2);
- grid.attach (scrolled, 0, 3);
- grid.attach (button_grid, 0, 4);
-
- var content_area = get_content_area ();
- content_area.border_width = 12;
- content_area.add (grid);
- }
-}
diff --git a/src/Dialogs/SettingsDialog.vala b/src/Dialogs/SettingsDialog.vala
deleted file mode 100644
index 427d6b61e..000000000
--- a/src/Dialogs/SettingsDialog.vala
+++ /dev/null
@@ -1,430 +0,0 @@
-/*
-* Copyright (c) 2019-2020 Alecaddd (https://alecaddd.com)
-*
-* This file is part of Akira.
-*
-* Akira 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.
-
-* Akira 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 Akira. If not, see .
-*
-* Authored by: Alessandro "Alecaddd" Castellani
-*/
-
-public class Akira.Dialogs.SettingsDialog : Gtk.Dialog {
- public weak Akira.Window window { get; construct; }
- private Gtk.Stack stack;
- private Gtk.Switch dark_theme_switch;
- private Gtk.Switch follow_system_switch;
- private Gtk.Switch label_switch;
- private Gtk.Switch symbolic_switch;
- private Gtk.Switch border_switch;
- private Gtk.ColorButton grid_color;
- private Gtk.ColorButton snaps_color;
- private Gtk.ColorButton fill_color;
- private Gtk.ColorButton border_color;
- private Gtk.SpinButton border_size;
-
- public SettingsDialog (Akira.Window _window) {
- Object (
- window: _window,
- border_width: 6,
- deletable: true,
- resizable: false,
- modal: true,
- title: _("Preferences")
- );
- }
-
- construct {
- transient_for = window;
- stack = new Gtk.Stack ();
- stack.margin = 6;
- stack.margin_bottom = 15;
- stack.margin_top = 15;
- stack.add_titled (get_general_box (), "general", _("General"));
- stack.add_titled (get_interface_box (), "interface", _("Interface"));
- stack.add_titled (get_canvas_box (), "canvas", _("Canvas"));
- stack.add_titled (get_shapes_box (), "shapes", _("Shapes"));
- stack.add_titled (get_about_box (), "about", _("About"));
-
- var stack_switcher = new Gtk.StackSwitcher ();
- stack_switcher.set_stack (stack);
- stack_switcher.halign = Gtk.Align.CENTER;
-
- var grid = new Gtk.Grid ();
- grid.halign = Gtk.Align.CENTER;
- grid.attach (stack_switcher, 1, 1, 1, 1);
- grid.attach (stack, 1, 2, 1, 1);
-
- get_content_area ().add (grid);
- }
-
- private Gtk.Widget get_general_box () {
- var grid = new Gtk.Grid ();
- grid.row_spacing = 6;
- grid.column_spacing = 12;
- grid.column_homogeneous = true;
-
- grid.attach (new SettingsHeader (_("General")), 0, 0, 2, 1);
- grid.attach (new SettingsLabel (_("Auto Reopen Latest File:")), 0, 1, 1, 1);
- grid.attach (new SettingsSwitch ("open-quick"), 1, 1, 1, 1);
-
- return grid;
- }
-
- private Gtk.Widget get_interface_box () {
- var grid = new Gtk.Grid ();
- grid.row_spacing = 6;
- grid.column_spacing = 12;
- grid.column_homogeneous = true;
-
- grid.attach (new SettingsHeader (_("Interface")), 0, 0, 2, 1);
-
- grid.attach (new SettingsLabel (_("Use Dark Theme:")), 0, 1, 1, 1);
- dark_theme_switch = new SettingsSwitch ("dark-theme");
- dark_theme_switch.sensitive = !settings.follow_system_theme;
- grid.attach (dark_theme_switch, 1, 1, 1, 1);
-
- grid.attach (new SettingsLabel (_("Follow the system theme variation:")), 0, 2, 1, 1);
- follow_system_switch = new SettingsSwitch ("follow-system-theme");
- grid.attach (follow_system_switch, 1, 2, 1, 1);
-
- var theme_helper_label = new Gtk.Label (_("If enabled, the Dark Theme switch will be disabled."));
- theme_helper_label.get_style_context ().add_class ("dim-label");
- theme_helper_label.halign = Gtk.Align.START;
- grid.attach (theme_helper_label, 1, 3, 1, 1);
-
- grid.attach (new SettingsLabel (_("Invert Panels Order:")), 0, 4, 1, 1);
- symbolic_switch = new SettingsSwitch ("invert-sidebar");
- grid.attach (symbolic_switch, 1, 4, 1, 1);
-
- var panels_helper_label = new Gtk.Label (_("Restart application to apply this change."));
- panels_helper_label.get_style_context ().add_class ("dim-label");
- panels_helper_label.halign = Gtk.Align.START;
- grid.attach (panels_helper_label, 1, 5, 1, 1);
-
- grid.attach (new SettingsHeader (_("ToolBar Style")), 0, 6, 2, 1);
-
- grid.attach (new SettingsLabel (_("Show Button Labels:")), 0, 7, 1, 1);
- label_switch = new SettingsSwitch ("show-label");
- grid.attach (label_switch, 1, 7, 1, 1);
-
- grid.attach (new SettingsLabel (_("Use Symbolic Icons:")), 0, 8, 1, 1);
- symbolic_switch = new SettingsSwitch ("use-symbolic");
- grid.attach (symbolic_switch, 1, 8, 1, 1);
-
- dark_theme_switch.notify["active"].connect (() => {
- Gtk.Settings.get_default ().gtk_application_prefer_dark_theme = settings.dark_theme;
- window.event_bus.change_theme ();
- });
-
- follow_system_switch.notify["active"].connect (() => {
- if (settings.follow_system_theme) {
- dark_theme_switch.sensitive = false;
- Gtk.Settings.get_default ().gtk_application_prefer_dark_theme = Granite.Settings.get_default ().prefers_color_scheme == Granite.Settings.ColorScheme.DARK;
- return;
- }
- dark_theme_switch.sensitive = true;
- Gtk.Settings.get_default ().gtk_application_prefer_dark_theme = settings.dark_theme;
- });
-
- return grid;
- }
-
- private Gtk.Widget get_canvas_box () {
- var grid = new Gtk.Grid ();
- grid.row_spacing = 6;
- grid.column_spacing = 12;
- grid.column_homogeneous = true;
-
- // Pixel grid.
- var grid_rgba = Gdk.RGBA ();
- grid_rgba.parse (settings.grid_color);
-
- grid.attach (new SettingsHeader (_("Pixel Grid")), 0, 0, 2, 1);
-
- var description = new Gtk.Label (_("Define the default color for the Canvas pixel grid."));
- description.halign = Gtk.Align.START;
- description.margin_bottom = 10;
- grid.attach (description, 0, 1, 2, 1);
-
- grid.attach (new SettingsLabel (_("Pixel Grid Color:")), 0, 2, 1, 1);
- grid_color = new Gtk.ColorButton.with_rgba (grid_rgba);
- grid_color.halign = Gtk.Align.START;
- grid.attach (grid_color, 1, 2, 1, 1);
-
- grid_color.color_set.connect (() => {
- var rgba = grid_color.get_rgba ();
-
- // Gdk.RGBA uses rgb() if alpha is 1.
- string rgba_str = "rgba(%d,%d,%d,%d)".printf (
- (int) (rgba.red * 255),
- (int) (rgba.green * 255),
- (int) (rgba.blue * 255),
- (int) (rgba.alpha)
- );
-
- debug ("pixel grid color: %s", rgba_str);
-
- settings.grid_color = rgba_str;
- window.event_bus.update_pixel_grid ();
- });
-
- // Snapping guides.
- var snaps_rgba = Gdk.RGBA ();
- snaps_rgba.parse (settings.snaps_color);
-
- grid.attach (new SettingsHeader (_("Snapping Guides")), 0, 3, 2, 1);
-
- var snaps_description = new Gtk.Label (_("Define the default options for the Snapping Guides."));
- snaps_description.halign = Gtk.Align.START;
- snaps_description.margin_bottom = 10;
- grid.attach (snaps_description, 0, 4, 2, 1);
-
- grid.attach (new SettingsLabel (_("Enable Snapping Guides:")), 0, 5, 1, 1);
- var snaps_switch = new SettingsSwitch ("enable-snaps");
- grid.attach (snaps_switch, 1, 5, 1, 1);
-
- grid.attach (new SettingsLabel (_("Snapping Guides Color:")), 0, 6, 1, 1);
- snaps_color = new Gtk.ColorButton.with_rgba (snaps_rgba);
- snaps_color.halign = Gtk.Align.START;
- grid.attach (snaps_color, 1, 6, 1, 1);
-
- snaps_color.color_set.connect (() => {
- var rgba = snaps_color.get_rgba ();
-
- // Gdk.RGBA uses rgb() if alpha is 1.
- string rgba_str = "rgba(%d,%d,%d,%d)".printf (
- (int) (rgba.red * 255),
- (int) (rgba.green * 255),
- (int) (rgba.blue * 255),
- (int) (rgba.alpha)
- );
-
- debug ("pixel snaps color: %s", rgba_str);
-
- settings.snaps_color = rgba_str;
- window.event_bus.update_snaps_color ();
- });
-
- grid.attach (new SettingsLabel (_("Snapping Sensitivity Threshold:")), 0, 7, 1, 1);
- var snaps_sensitivity = new Gtk.SpinButton.with_range (0, 9999, 1);
- snaps_sensitivity.halign = Gtk.Align.START;
- snaps_sensitivity.width_chars = 6;
- snaps_sensitivity.get_style_context ().add_class ("input-icon-right");
- snaps_sensitivity.secondary_icon_name = "input-pixel-symbolic";
- snaps_sensitivity.secondary_icon_sensitive = false;
- snaps_sensitivity.secondary_icon_activatable = false;
- grid.attach (snaps_sensitivity, 1, 7, 1, 1);
-
- settings.bind ("snaps-sensitivity", snaps_sensitivity, "value", SettingsBindFlags.DEFAULT);
-
- snaps_switch.bind_property ("active", snaps_color, "sensitive", BindingFlags.SYNC_CREATE);
- snaps_switch.bind_property ("active", snaps_sensitivity, "sensitive", BindingFlags.SYNC_CREATE);
-
- return grid;
- }
-
- private Gtk.Widget get_shapes_box () {
- var grid = new Gtk.Grid ();
- grid.row_spacing = 6;
- grid.column_spacing = 12;
- grid.column_homogeneous = true;
-
- var fill_rgba = Gdk.RGBA ();
- fill_rgba.parse (settings.fill_color);
- var border_rgba = Gdk.RGBA ();
- border_rgba.parse (settings.border_color);
-
- grid.attach (new SettingsHeader (_("Default Colors")), 0, 0, 2, 1);
-
- var description = new Gtk.Label (_("Define the default style used when creating a new shape."));
- description.halign = Gtk.Align.START;
- description.margin_bottom = 10;
- grid.attach (description, 0, 1, 2, 1);
-
- grid.attach (new SettingsLabel (_("Fill Color:")), 0, 2, 1, 1);
- fill_color = new Gtk.ColorButton.with_rgba (fill_rgba);
- fill_color.halign = Gtk.Align.START;
- grid.attach (fill_color, 1, 2, 1, 1);
-
- fill_color.color_set.connect (() => {
- var rgba = fill_color.get_rgba ();
-
- // Gdk.RGBA uses rgb() if alpha is 1.
- string rgba_str = "rgba(%d,%d,%d,%d)".printf (
- (int) (rgba.red * 255),
- (int) (rgba.green * 255),
- (int) (rgba.blue * 255),
- (int) (rgba.alpha)
- );
-
- debug ("setting color: %s", rgba_str);
-
- settings.fill_color = rgba_str;
- });
-
- grid.attach (new SettingsLabel (_("Enable Border Style:")), 0, 3, 1, 1);
- border_switch = new SettingsSwitch ("set-border");
- grid.attach (border_switch, 1, 3, 1, 1);
- grid.attach (new SettingsLabel (_("Border Color:")), 0, 4, 1, 1);
- border_color = new Gtk.ColorButton.with_rgba (border_rgba);
- border_color.halign = Gtk.Align.START;
- grid.attach (border_color, 1, 4, 1, 1);
-
- border_color.color_set.connect (() => {
- var rgba = border_color.get_rgba ();
-
- // Gdk.RGBA uses rgb() if alpha is 1.
- string rgba_str = "rgba(%d,%d,%d,%d)".printf (
- (int) (rgba.red * 255),
- (int) (rgba.green * 255),
- (int) (rgba.blue * 255),
- (int) (rgba.alpha)
- );
-
- debug ("setting color: %s", rgba_str);
-
- settings.border_color = rgba_str;
- });
-
- grid.attach (new SettingsLabel (_("Border Width:")), 0, 5, 1, 1);
- border_size = new Gtk.SpinButton.with_range (1, 9999, 1);
- border_size.halign = Gtk.Align.START;
- border_size.width_chars = 6;
- border_size.get_style_context ().add_class ("input-icon-right");
- border_size.secondary_icon_name = "input-pixel-symbolic";
- border_size.secondary_icon_sensitive = false;
- border_size.secondary_icon_activatable = false;
- grid.attach (border_size, 1, 5, 1, 1);
-
- settings.bind ("border-size", border_size, "value", SettingsBindFlags.DEFAULT);
-
- border_switch.bind_property ("active", border_color, "sensitive", BindingFlags.SYNC_CREATE);
- border_switch.bind_property ("active", border_size, "sensitive", BindingFlags.SYNC_CREATE);
-
- return grid;
- }
-
- private Gtk.Widget get_about_box () {
- var grid = new Gtk.Grid ();
- grid.row_spacing = 6;
- grid.column_spacing = 12;
- grid.halign = Gtk.Align.CENTER;
-
- var app_icon = new Gtk.Image ();
- app_icon.gicon = new ThemedIcon (Constants.APP_ID);
- app_icon.pixel_size = 64;
- app_icon.margin_top = 12;
-
- var app_name = new Gtk.Label (Constants.APP_NAME);
- app_name.get_style_context ().add_class ("h2");
- app_name.margin_top = 6;
-
- var app_description = new Gtk.Label (_("The Linux Design Tool"));
- app_description.get_style_context ().add_class ("h3");
-
- var app_version = new Gtk.Label ("v" + Constants.VERSION + " - alpha");
- app_version.get_style_context ().add_class ("dim-label");
- app_version.selectable = true;
-
- var disclaimer = new Gtk.Label (
- _("WARNING!\nAkira is still under development and not ready for production. Missing features, random bugs, and black holes opening in your kitchen are to be expected."
- )
- );
- disclaimer.justify = Gtk.Justification.CENTER;
- disclaimer.get_style_context ().add_class ("warning-message");
- disclaimer.max_width_chars = 60;
- disclaimer.wrap = true;
- disclaimer.margin_top = disclaimer.margin_bottom = 12;
-
- var patreons_label = new Gtk.Label (_("Thanks to our awesome supporters!"));
- patreons_label.get_style_context ().add_class ("h4");
-
- var patreons_url = new Gtk.LinkButton.with_label (
- "https://github.com/akiraux/Akira/blob/master/SUPPORTERS.md",
- _("View the list of supporters")
- );
- patreons_url.halign = Gtk.Align.CENTER;
- patreons_url.margin_bottom = 12;
-
- grid.attach (app_icon, 0, 0);
- grid.attach (app_name, 0, 1);
- grid.attach (app_description, 0, 2);
- grid.attach (app_version, 0, 3);
- grid.attach (disclaimer, 0, 4);
- grid.attach (patreons_label, 0, 5);
- grid.attach (patreons_url, 0, 6);
-
- // Button grid at the bottom of the About page.
- var button_grid = new Gtk.ButtonBox (Gtk.Orientation.HORIZONTAL);
- button_grid.halign = Gtk.Align.CENTER;
- button_grid.spacing = 6;
-
- var donate_button = new Gtk.Button.with_label (_("Make a Donation"));
- donate_button.clicked.connect (() => {
- try {
- AppInfo.launch_default_for_uri ("https://github.com/akiraux/Akira#-support", null);
- } catch (Error e) {
- warning (e.message);
- }
- });
-
- var translate_button = new Gtk.Button.with_label (_("Suggest Translations"));
- translate_button.clicked.connect (() => {
- try {
- AppInfo.launch_default_for_uri ("https://github.com/akiraux/Akira/issues", null);
- } catch (Error e) {
- warning (e.message);
- }
- });
-
- var bug_button = new Gtk.Button.with_label (_("Report a Problem"));
- bug_button.clicked.connect (() => {
- try {
- AppInfo.launch_default_for_uri ("https://github.com/akiraux/Akira/issues", null);
- } catch (Error e) {
- warning (e.message);
- }
- });
-
- button_grid.add (donate_button);
- button_grid.add (translate_button);
- button_grid.add (bug_button);
-
- grid.attach (button_grid, 0, 7);
-
- return grid;
- }
-
- private class SettingsHeader : Gtk.Label {
- public SettingsHeader (string text) {
- label = text;
- get_style_context ().add_class ("h4");
- halign = Gtk.Align.START;
- }
- }
-
- private class SettingsLabel : Gtk.Label {
- public SettingsLabel (string text) {
- label = text;
- halign = Gtk.Align.END;
- }
- }
-
- private class SettingsSwitch : Gtk.Switch {
- public SettingsSwitch (string setting) {
- halign = Gtk.Align.START;
- settings.bind (setting, this, "active", SettingsBindFlags.DEFAULT);
- }
- }
-}
diff --git a/src/Dialogs/ShortcutsDialog.vala b/src/Dialogs/ShortcutsDialog.vala
deleted file mode 100644
index 9049702e6..000000000
--- a/src/Dialogs/ShortcutsDialog.vala
+++ /dev/null
@@ -1,157 +0,0 @@
-/*
-* Copyright (c) 2020 Alecaddd (https://alecaddd.com)
-*
-* This file is part of Akira.
-*
-* Akira 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.
-
-* Akira 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 Akira. If not, see .
-*
-* Authored by: Alessandro "Alecaddd" Castellani
-*/
-
-public class Akira.Dialogs.ShortcutsDialog : Gtk.Dialog {
- public weak Akira.Window window { get; construct; }
-
- public ShortcutsDialog (Akira.Window window) {
- Object (
- window: window,
- border_width: 10,
- deletable: true,
- resizable: true,
- modal: true
- );
- }
-
- construct {
- transient_for = window;
- default_width = 800;
-
- var column_start = new Gtk.Grid ();
- column_start.column_spacing = 12;
- column_start.row_spacing = 12;
- column_start.hexpand = true;
- column_start.column_homogeneous = true;
-
- column_start.attach (new Granite.HeaderLabel (_("General")), 0, 0, 2);
- column_start.attach (new NameLabel (_("New window:")), 0, 1);
- column_start.attach (new ShortcutLabel ({"Ctrl", "N"}), 1, 1);
- column_start.attach (new NameLabel (_("Preferences:")), 0, 2);
- column_start.attach (new ShortcutLabel ({"Ctrl", ","}), 1, 2);
- column_start.attach (new NameLabel (_("Quit:")), 0, 3);
- column_start.attach (new ShortcutLabel ({"Ctrl", "Q"}), 1, 3);
- column_start.attach (new NameLabel (_("Presentation mode:")), 0, 4);
- column_start.attach (new ShortcutLabel ({"Ctrl", "."}), 1, 4);
-
- column_start.attach (new Granite.HeaderLabel (_("File")), 0, 5, 2);
- column_start.attach (new NameLabel (_("Open:")), 0, 6);
- column_start.attach (new ShortcutLabel ({"Ctrl", "O"}), 1, 6);
- column_start.attach (new NameLabel (_("Save:")), 0, 7);
- column_start.attach (new ShortcutLabel ({"Ctrl", "S"}), 1, 7);
- column_start.attach (new NameLabel (_("Save as:")), 0, 8);
- column_start.attach (new ShortcutLabel ({"Ctrl", "Shift", "S"}), 1, 8);
-
- column_start.attach (new Granite.HeaderLabel (_("Export")), 0, 9, 2);
- column_start.attach (new NameLabel (_("Export artboards:")), 0, 10);
- column_start.attach (new ShortcutLabel ({"Ctrl", "Alt", "A"}), 1, 10);
- column_start.attach (new NameLabel (_("Export selection:")), 0, 11);
- column_start.attach (new ShortcutLabel ({"Ctrl", "Alt", "E"}), 1, 11);
- column_start.attach (new NameLabel (_("Highlight area to export:")), 0, 12);
- column_start.attach (new ShortcutLabel ({"Ctrl", "Alt", "G"}), 1, 12);
-
- var column_end = new Gtk.Grid ();
- column_end.column_spacing = 12;
- column_end.row_spacing = 12;
- column_end.hexpand = true;
- column_end.column_homogeneous = true;
-
- column_end.attach (new Granite.HeaderLabel (_("Canvas")), 0, 0, 2);
- column_end.attach (new NameLabel (_("Zoom in:")), 0, 1);
- column_end.attach (new ShortcutLabel ({"Ctrl", "+"}), 1, 1);
- column_end.attach (new NameLabel (_("Zoom out:")), 0, 2);
- column_end.attach (new ShortcutLabel ({"Ctrl", "-"}), 1, 2);
- column_end.attach (new NameLabel (_("Zoom reset:")), 0, 3);
- column_end.attach (new ShortcutLabel ({"Ctrl", "0"}), 1, 3);
-
- column_end.attach (new Granite.HeaderLabel (_("Item creation")), 0, 4, 2);
- column_end.attach (new NameLabel (_("Artboard:")), 0, 5);
- column_end.attach (new ShortcutLabel ({"A"}), 1, 5);
- column_end.attach (new NameLabel (_("Rectangle:")), 0, 6);
- column_end.attach (new ShortcutLabel ({"R"}), 1, 6);
- column_end.attach (new NameLabel (_("Ellipse:")), 0, 7);
- column_end.attach (new ShortcutLabel ({"E"}), 1, 7);
- column_end.attach (new NameLabel (_("Text:")), 0, 8);
- column_end.attach (new ShortcutLabel ({"T"}), 1, 8);
- column_end.attach (new NameLabel (_("Image:")), 0, 9);
- column_end.attach (new ShortcutLabel ({"I"}), 1, 9);
-
- column_end.attach (new Granite.HeaderLabel (_("Transform")), 0, 10, 2);
- column_end.attach (new NameLabel (_("Raise selection:")), 0, 11);
- column_end.attach (new ShortcutLabel ({"Ctrl", "↑"}), 1, 11);
- column_end.attach (new NameLabel (_("Lower selection:")), 0, 12);
- column_end.attach (new ShortcutLabel ({"Ctrl", "↓"}), 1, 12);
- column_end.attach (new NameLabel (_("Raise selection to top:")), 0, 13);
- column_end.attach (new ShortcutLabel ({"Ctrl", "Shift", "↑"}), 1, 13);
- column_end.attach (new NameLabel (_("Lower selection to bottom:")), 0, 14);
- column_end.attach (new ShortcutLabel ({"Ctrl", "Shift", "↓"}), 1, 14);
- column_end.attach (new NameLabel (_("Flip horizontally:")), 0, 15);
- column_end.attach (new ShortcutLabel ({"Ctrl", "["}), 1, 15);
- column_end.attach (new NameLabel (_("Flip vertically:")), 0, 16);
- column_end.attach (new ShortcutLabel ({"Ctrl", "]"}), 1, 16);
-
- var grid = new Gtk.Grid ();
- grid.column_spacing = 12;
- grid.hexpand = true;
- grid.attach (column_start, 0, 0);
- grid.attach (new Gtk.Separator (Gtk.Orientation.VERTICAL), 1, 0);
- grid.attach (column_end, 2, 0);
-
- var content_area = get_content_area ();
- content_area.border_width = 12;
- content_area.add (grid);
- }
-
- private class NameLabel : Gtk.Label {
- public NameLabel (string label) {
- Object (
- label: label
- );
- }
-
- construct {
- halign = Gtk.Align.END;
- xalign = 1;
- }
- }
-
- private class ShortcutLabel : Gtk.Grid {
- public string[] accels { get; set construct; }
-
- public ShortcutLabel (string[] accels) {
- Object (accels: accels);
- }
-
- construct {
- column_spacing = 6;
-
- foreach (unowned string accel in accels) {
- if (accel == "") {
- continue;
- }
- var label = new Gtk.Label (accel);
- label.get_style_context ().add_class ("keycap");
- add (label);
- }
- halign = Gtk.Align.START;
- }
- }
-}
diff --git a/src/Drawables/Drawable.vala b/src/Drawables/Drawable.vala
deleted file mode 100644
index 42d4b787c..000000000
--- a/src/Drawables/Drawable.vala
+++ /dev/null
@@ -1,405 +0,0 @@
-/**
- * Copyright (c) 2019-2021 Alecaddd (https://alecaddd.com)
- *
- * This file is part of Akira.
- *
- * Akira 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.
-
- * Akira 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 Akira. If not, see .
- *
- * Authored by: Martin "mbfraga" Fraga
- */
-
-/*
- * Overrides methods in Goo.CanvasItemSimple to handle a few things differently:
- * 1. Have uniform strokes in transformed objects.
- * 2. Add a clipping quad to make clipping more efficient.
- */
-public class Akira.Drawables.Drawable {
- public enum HitTestType {
- SELECT,
- GROUP_REGION
- }
-
- public enum BorderType {
- CENTER,
- INSIDE,
- OUTSIDE
- }
-
- public enum DrawType {
- NORMAL,
- XRAY
- }
-
- // Style
- public double line_width { get; set; default = 0; }
- public Gdk.RGBA fill_rgba { get; set; default = Gdk.RGBA (); }
- public Gdk.RGBA stroke_rgba { get; set; default = Gdk.RGBA (); }
- public BorderType border_type { get; set; default = BorderType.CENTER; }
- public double radius_tr { get; set; default = 0; }
- public double radius_tl { get; set; default = 0; }
- public double radius_br { get; set; default = 0; }
- public double radius_bl { get; set; default = 0; }
-
- public int parent_id { get; set; default = -1; }
- public string label { get; set; default = ""; }
- public double center_x { get; set; default = 0; }
- public double center_y { get; set; default = 0; }
- public double width { get; set; default = 0; }
- public double height { get; set; default = 0; }
- public Cairo.Matrix transform { get; set; default = Cairo.Matrix.identity (); }
-
- public Geometry.Rectangle bounds { get; set; default = Geometry.Rectangle (); }
-
- // Clipping path in global reference frame
- public Geometry.Quad? clipping_path = null;
-
- // Convenience getters
- public bool has_radius { get { return (radius_tr + radius_tl + radius_br + radius_bl) > 0; } }
-
- public bool is_drawn = false;
-
- /*
- * Return true if the position x,y in local coordinates is inside of the selectable
- * area of a drawable.
- */
- public virtual bool hit_test (
- double x,
- double y,
- Cairo.Context context,
- double scale,
- HitTestType hit_test_type
- ) {
- if (hit_test_type == GROUP_REGION) {
- return false;
- }
-
- double user_x = x, user_y = y;
- bool add_item = false;
-
- // Ignore if out of bounds
- if (bounds.does_not_contain (x, y)) {
- return false;
- }
-
- Cairo.Matrix global_transform = context.get_matrix ();
- context.save ();
-
- Cairo.Matrix tr = transform;
- context.transform (tr);
-
- // Account for clipping path first, since they should be in the global reference
- if (clipping_path != null) {
- context.move_to (clipping_path.tl_x, clipping_path.tl_y);
- context.line_to (clipping_path.tr_x, clipping_path.tr_y);
- context.line_to (clipping_path.br_x, clipping_path.br_y);
- context.line_to (clipping_path.bl_x, clipping_path.bl_y);
- context.close_path ();
-
- context.set_fill_rule (Cairo.FillRule.WINDING);
- if (!context.in_fill (user_x, user_y)) {
- context.restore ();
- context.new_path ();
- return false;
- }
- }
-
- context.device_to_user (ref user_x, ref user_y);
-
- /* Remove any current translation, to avoid the 16-bit cairo limit. */
- var tmp = context.get_matrix ();
- tmp.x0 = 0.0;
- tmp.y0 = 0.0;
- context.set_matrix (tmp);
-
- simple_create_path (context);
-
- /* Check the filled path, if required. */
- if (set_fill_options (context, DrawType.NORMAL)) {
- if (context.in_fill (user_x, user_y)) {
- add_item = true;
- }
- }
-
- /* Check the stroke, if required. */
- if (set_stroke_options (context, DrawType.NORMAL)) {
- context.set_matrix (global_transform);
- user_x = x - tr.x0;
- user_y = y - tr.y0;
-
- if (context.in_stroke (user_x, user_y)) {
- add_item = true;
- }
- }
-
- context.restore ();
- context.new_path ();
-
- return add_item;
- }
-
- /*
- * Create the path for an drawable, used in other methods.
- */
- public virtual void simple_create_path (Cairo.Context context) {}
-
- /*
- * Main paint method.
- */
- public virtual void paint (Cairo.Context context, Geometry.Rectangle target_bounds, double scale, DrawType draw_type) {
- // Simple bounds check
- if (bounds.left > target_bounds.right || bounds.right < target_bounds.left
- || bounds.top > target_bounds.bottom || bounds.bottom < target_bounds.top) {
- return;
- }
-
- Cairo.Matrix global_transform = context.get_matrix ();
-
- context.save ();
-
- var normal_draw = draw_type == DrawType.NORMAL;
-
- // The clipping path is in global coordinates, so we can ignore the transformation.
- if (normal_draw && clipping_path != null) {
- context.move_to (clipping_path.tl_x, clipping_path.tl_y);
- context.line_to (clipping_path.tr_x, clipping_path.tr_y);
- context.line_to (clipping_path.br_x, clipping_path.br_y);
- context.line_to (clipping_path.bl_x, clipping_path.bl_y);
- context.close_path ();
- context.set_fill_rule (Cairo.FillRule.WINDING);
- context.clip ();
- }
-
- // We apply the item transform before creating the path
- Cairo.Matrix tr = transform;
- context.transform (tr);
-
- simple_create_path (context);
-
- if (set_fill_options (context, draw_type)) {
- context.fill_preserve ();
- }
-
- // We restore the global transformation to draw strokes with uniform width. Changing
- // the matrix does not affect the path already generated.
- context.set_matrix (global_transform);
-
- if (set_stroke_options (context, draw_type)) {
- context.stroke ();
- }
-
- context.restore ();
-
- // Very important to initialize new path
- context.new_path ();
-
- is_drawn = true;
- }
-
- /*
- * Hover paint method for the drawable.
- */
- public virtual void paint_hover (
- Cairo.Context context,
- Gdk.RGBA color,
- double line_width,
- Geometry.Rectangle target_bounds,
- double scale
- ) {
- context.save ();
- Cairo.Matrix global_transform = context.get_matrix ();
-
- // We apply the item transform before creating the path
- Cairo.Matrix tr = transform;
- context.transform (tr);
-
- simple_create_path (context);
-
- context.set_line_width (line_width / scale);
- context.set_source_rgba (color.red, color.green, color.blue, color.alpha);
- context.set_matrix (global_transform);
- context.stroke ();
-
- context.restore ();
-
- // Very important to initialize new path
- context.new_path ();
- }
-
- /*
- * Create a target like element on top of the drawable to represent the
- * current subselection anchor point that will be used as alignment pivot.
- */
- public virtual void paint_anchor (
- Cairo.Context context,
- Gdk.RGBA color,
- double line_width,
- double scale
- ) {
- context.save ();
-
- // We apply the item transform before creating the path
- Cairo.Matrix tr = transform;
- context.transform (tr);
-
- // Set the visual properties.
- context.set_line_width (line_width / scale);
- context.set_source_rgba (color.red, color.green, color.blue, color.alpha);
-
- // Create the circle.
- context.new_path ();
- context.arc (0.0, 0.0, 5 / scale, 0.0, 2.0 * GLib.Math.PI);
- // Draw the circle and preserve the visual properties.
- context.stroke ();
-
- var length = 10 / scale;
- // Create the horizontal stroke.
- context.new_path ();
- context.move_to (-length, 0);
- context.line_to (length, 0);
- context.stroke ();
-
- // Create the vertical stroke.
- context.new_path ();
- context.move_to (0, -length);
- context.line_to (0, length);
- context.stroke ();
- context.restore ();
-
- // Very important to initialize new path
- context.new_path ();
- }
-
- /*
- * Generates the bounding box for the drawable.
- */
- public virtual Geometry.Rectangle generate_bounding_box () {
- double x1 = 0;
- double x2 = 0;
- double y1 = 0;
- double y2 = 0;
-
- Cairo.ImageSurface surface = new Cairo.ImageSurface (Cairo.Format.A1, 1, 1);
- Cairo.Context context = new Cairo.Context (surface);
-
- context.set_antialias (Cairo.Antialias.GRAY);
-
- Cairo.Matrix tr = transform;
- context.transform (tr);
-
- double translate_x = tr.x0;
- double translate_y = tr.y0;
-
- var fill_bounds = Geometry.Rectangle ();
- var stroke_bounds = Geometry.Rectangle ();
-
- set_fill_options (context, DrawType.NORMAL);
-
- simple_create_path (context);
-
- context.set_matrix (Cairo.Matrix (1.0, 0.0, 0.0, 1.0, translate_x, translate_y));
-
- context.fill_extents (
- out fill_bounds.left,
- out fill_bounds.top,
- out fill_bounds.right,
- out fill_bounds.bottom
- );
-
- set_stroke_options (context, DrawType.NORMAL);
-
- context.stroke_extents (
- out stroke_bounds.left,
- out stroke_bounds.top,
- out stroke_bounds.right,
- out stroke_bounds.bottom
- );
-
- if (fill_bounds.left == 0.0 && fill_bounds.right == 0.0) {
- /* The fill bounds are empty so just use the stroke bounds.
- If the stroke bounds are also empty the bounds will be all 0.0. */
- x1 = stroke_bounds.left;
- x2 = stroke_bounds.right;
- y1 = stroke_bounds.top;
- y2 = stroke_bounds.bottom;
- } else if (stroke_bounds.left == 0.0 && stroke_bounds.right == 0.0) {
- /* The stroke bounds are empty so just use the fill bounds. */
- x1 = fill_bounds.left;
- x2 = fill_bounds.right;
- y1 = fill_bounds.top;
- y2 = fill_bounds.bottom;
- } else {
- /* Both fill & stoke bounds are non-empty so combine them. */
- Utils.GeometryMath.min_max_coords (
- fill_bounds.left,
- fill_bounds.right,
- stroke_bounds.left,
- stroke_bounds.right,
- ref x1,
- ref x2
- );
-
- Utils.GeometryMath.min_max_coords (
- fill_bounds.top,
- fill_bounds.bottom,
- stroke_bounds.top,
- stroke_bounds.bottom,
- ref y1,
- ref y2
- );
- }
-
- return Geometry.Rectangle.with_coordinates (
- x1 + translate_x,
- y1 + translate_y,
- x2 + translate_x,
- y2 + translate_y
- );
- }
-
- public virtual void request_redraw (ViewLayers.BaseCanvas canvas, bool recalculate_bounds) {
- if (recalculate_bounds) {
- bounds = generate_bounding_box ();
- }
- else if (!is_drawn) {
- // This request is to clear the old draw, but since it was never drawn, we can ignore.
- return;
- }
-
- canvas.request_redraw (bounds);
- }
-
- public bool set_fill_options (Cairo.Context context, DrawType draw_type) {
- if (draw_type == DrawType.XRAY) {
- return false;
- }
- context.set_source_rgba (fill_rgba.red, fill_rgba.green, fill_rgba.blue, fill_rgba.alpha);
- context.set_antialias (Cairo.Antialias.GRAY);
- return true;
- }
-
- public bool set_stroke_options (Cairo.Context context, DrawType draw_type) {
- if (draw_type == DrawType.XRAY) {
- context.set_source_rgba (0.0, 0.0, 0.0, 1.0);
- context.set_line_width (1);
- context.set_antialias (Cairo.Antialias.GRAY);
- return true;
- }
-
- context.set_source_rgba (stroke_rgba.red, stroke_rgba.green, stroke_rgba.blue, stroke_rgba.alpha);
- context.set_line_width (line_width);
- context.set_antialias (Cairo.Antialias.GRAY);
- return line_width > 0;
- }
-
-}
diff --git a/src/Drawables/DrawableArtboard.vala b/src/Drawables/DrawableArtboard.vala
deleted file mode 100644
index e18012aaa..000000000
--- a/src/Drawables/DrawableArtboard.vala
+++ /dev/null
@@ -1,185 +0,0 @@
-/**
- * Copyright (c) 2019-2021 Alecaddd (https://alecaddd.com)
- *
- * This file is part of Akira.
- *
- * Akira 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.
-
- * Akira 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 Akira. If not, see .
- *
- * Authored by: Martin "mbfraga" Fraga
- */
-
-/*
- * Drawable for artboards.
- */
-public class Akira.Drawables.DrawableArtboard : Drawable {
- private const double LABEL_HEIGHT = 20;
- private const double LABEL_MARGIN = 5;
-
- public DrawableArtboard (double tl_x, double tl_y, double width, double height) {
- this.center_x = tl_x + width / 2.0;
- this.center_y = tl_y + height / 2.0;
- this.width = width;
- this.height = height;
- }
-
- public override bool hit_test (
- double x,
- double y,
- Cairo.Context context,
- double scale,
- Drawable.HitTestType hit_test_type
- ) {
- if (hit_test_type == GROUP_REGION) {
- return base.hit_test (x, y, context, scale, Drawable.HitTestType.SELECT);
- }
-
- var lheight = LABEL_HEIGHT / scale;
- var lbot = bounds.top;
- var ltop = lbot - lheight;
-
- var m = label_margin (scale);
- var w = bounds.width - m * 2;
- if (w <= 0) {
- return false;
- }
-
- double extent_width = 0;
- create_pango_layout (context, label, w, scale, &extent_width);
- extent_width /= scale;
- return !(x < bounds.left || x > bounds.left + extent_width + m * 2 || y < ltop || y > lbot);
- }
-
- public override void simple_create_path (Cairo.Context context) {
- Drawables.DrawableRect.rect_path (context, this);
- }
-
- public override void paint (Cairo.Context context, Geometry.Rectangle target_bounds, double scale, Drawable.DrawType draw_type) {
- base.paint (context, target_bounds, scale, draw_type);
-
- draw_text (context, scale);
- }
-
- private void draw_text (Cairo.Context context, double scale) {
- var m = label_margin (scale);
- var w = bounds.width - m * 2;
- if (w <= 0) {
- return;
- }
-
- context.save ();
-
- if (settings.follow_system_theme) {
- var granite_settings = Granite.Settings.get_default ();
- if (granite_settings.prefers_color_scheme == Granite.Settings.ColorScheme.DARK) {
- context.set_source_rgba (1, 1, 1, 0.75);
- } else {
- context.set_source_rgba (0, 0, 0, 0.75);
- }
- } else {
- if (settings.dark_theme) {
- context.set_source_rgba (1, 1, 1, 0.75);
- } else {
- context.set_source_rgba (0, 0, 0, 0.75);
- }
- }
-
- var layout = create_pango_layout (context, label, w, scale, null);
- context.move_to (bounds.left + m, bounds.top - LABEL_HEIGHT / scale);
- context.scale (1 / scale, 1 / scale);
- Pango.cairo_show_layout (context, layout);
-
- context.restore ();
- context.new_path ();
- }
-
- private static Pango.Layout create_pango_layout (
- Cairo.Context context,
- string text,
- double layout_width,
- double scale,
- double* extent_width
- ) {
- var p_layout = Pango.cairo_create_layout (context);
- var p_context = p_layout.get_context ();
-
- if (layout_width > 0) {
- p_layout.set_width ( (int)(layout_width * Pango.SCALE));
- }
-
- p_layout.set_text (text, -1);
-
- // Load font description
- var desc = new Pango.FontDescription ();
- desc.set_family ("Open Sans");
- desc.set_size ((int) (10 * Pango.SCALE));
- p_layout.set_font_description (desc);
-
- // Load hint metrics
-
- var font_options = new Cairo.FontOptions ();
- font_options.set_hint_metrics (Cairo.HintMetrics.DEFAULT);
- Pango.cairo_context_set_font_options (p_context, font_options);
-
- p_layout.set_alignment (Pango.Alignment.LEFT);
- p_layout.set_ellipsize (Pango.EllipsizeMode.END);
- p_layout.set_wrap (Pango.WrapMode.WORD);
-
- if (extent_width != null) {
- Pango.Rectangle ink_rect;
- Pango.Rectangle logical_rect;
- p_layout.get_extents (out ink_rect, out logical_rect);
-
- var logical_width = (double) logical_rect.width / Pango.SCALE;
- *extent_width = logical_width;
- }
-
- return p_layout;
- }
-
- /*
- * Hover paint method for the drawable.
- */
- public override void paint_hover (
- Cairo.Context context,
- Gdk.RGBA color,
- double line_width,
- Geometry.Rectangle target_bounds,
- double scale
- ) {
- base.paint_hover (context, color, line_width, target_bounds, scale);
- }
-
- public override Geometry.Rectangle generate_bounding_box () {
- var r = base.generate_bounding_box ();
- return r;
- }
-
- public override void request_redraw (ViewLayers.BaseCanvas canvas, bool recalculate_bounds) {
- if (recalculate_bounds) {
- bounds = generate_bounding_box ();
- }
- else if (!is_drawn) {
- // This request is to clear the old draw, but since it was never drawn, we can ignore.
- return;
- }
-
- var tb = bounds;
- tb.top -= LABEL_HEIGHT / canvas.scale;
- canvas.request_redraw (tb);
- }
-
- protected double label_margin (double scale) {
- return LABEL_MARGIN / scale;
- }
-}
diff --git a/src/Drawables/DrawableEllipse.vala b/src/Drawables/DrawableEllipse.vala
deleted file mode 100644
index adc5dfc7d..000000000
--- a/src/Drawables/DrawableEllipse.vala
+++ /dev/null
@@ -1,49 +0,0 @@
-/**
- * Copyright (c) 2019-2021 Alecaddd (https://alecaddd.com)
- *
- * This file is part of Akira.
- *
- * Akira 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.
-
- * Akira 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 Akira. If not, see .
- *
- * Authored by: Martin "mbfraga" Fraga
- */
-
-/*
- * Drawable for ellipses.
- */
-public class Akira.Drawables.DrawableEllipse : Drawable {
- public double radius_x { get; set; default = 0; }
- public double radius_y { get; set; default = 0; }
-
- public DrawableEllipse (
- double center_x,
- double center_y,
- double radius_x,
- double radius_y
- ) {
- this.center_x = center_x;
- this.center_y = center_y;
- this.radius_x = radius_x;
- this.radius_y = radius_x;
- }
-
- public override void simple_create_path (Cairo.Context cr) {
- cr.save ();
- cr.new_path ();
- cr.translate (center_x, center_y);
- cr.scale (radius_x, radius_y);
- cr.arc (0.0, 0.0, 1.0, 0.0, 2.0 * GLib.Math.PI);
- cr.restore ();
- }
-}
diff --git a/src/Drawables/DrawableGroup.vala b/src/Drawables/DrawableGroup.vala
deleted file mode 100644
index 0b6c1211c..000000000
--- a/src/Drawables/DrawableGroup.vala
+++ /dev/null
@@ -1,62 +0,0 @@
-/**
- * Copyright (c) 2022 Alecaddd (https://alecaddd.com)
- *
- * This file is part of Akira.
- *
- * Akira 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.
-
- * Akira 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 Akira. If not, see .
- *
- * Authored by: Alessandro "Alecaddd" Castellani
- */
-
-/*
- * Drawable for groups.
- */
-public class Akira.Drawables.DrawableGroup : Drawable {
-
- public DrawableGroup () {}
-
- public override void simple_create_path (Cairo.Context context) {}
-
- public override void paint (Cairo.Context context, Geometry.Rectangle target_bounds, double scale, Drawable.DrawType draw_type) {}
-
- /*
- * Hover paint method for the drawable.
- */
- public override void paint_hover (
- Cairo.Context context,
- Gdk.RGBA color,
- double line_width,
- Geometry.Rectangle target_bounds,
- double scale
- ) {
- context.save ();
- Cairo.Matrix global_transform = context.get_matrix ();
-
- // We apply the item transform before creating the path.
- Cairo.Matrix tr = transform;
- context.transform (tr);
-
- context.rectangle (bounds.left, bounds.top, bounds.width, bounds.height);
-
- context.set_line_width (line_width / scale);
- context.set_source_rgba (color.red, color.green, color.blue, color.alpha);
- context.set_matrix (global_transform);
- context.stroke ();
-
- context.restore ();
-
- // Very important to initialize new path.
- context.new_path ();
- }
-}
diff --git a/src/Drawables/DrawablePath.vala b/src/Drawables/DrawablePath.vala
deleted file mode 100644
index 36da73a69..000000000
--- a/src/Drawables/DrawablePath.vala
+++ /dev/null
@@ -1,91 +0,0 @@
-/**
- * Copyright (c) 2019-2021 Alecaddd (https://alecaddd.com)
- *
- * This file is part of Akira.
- *
- * Akira 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.
-
- * Akira 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 Akira. If not, see .
- *
- * Authored by: Martin "mbfraga" Fraga
- */
-
-/*
- * Drawable for paths.
- */
-public class Akira.Drawables.DrawablePath : Drawable {
- // In the future we will probably want control points with more data.
-
- // This array stores the list of all points required to draw the point.
- public Geometry.PathSegment[]? points = null;
- // This flag tells us if the first and last point need to be joined.
- public bool close;
-
- public DrawablePath (Geometry.PathSegment[]? points = null, bool close = false) {
- if (points != null) {
- this.points = points;
- this.close = close;
- }
- }
-
- public override void simple_create_path (Cairo.Context cr) {
- if (points == null || points.length < 2) {
- return;
- }
-
- cr.save ();
- cr.translate (center_x, center_y);
- cr.new_path ();
- cr.move_to (points[0].line_end.x, points[0].line_end.y);
-
-
- for (int i = 0; i < points.length; ++i) {
- var point = points[i];
- if (point.type == Lib.Modes.PathEditMode.Type.LINE) {
- cr.line_to (point.line_end.x, point.line_end.y);
- } else if (point.type == Lib.Modes.PathEditMode.Type.QUADRATIC_LEFT) {
- var pb = points[i - 1].last_point;
- var cb = point.curve_begin;
- var t1 = point.tangent_1;
- cr.move_to (pb.x, pb.y);
- cr.curve_to (pb.x, pb.y, t1.x, t1.y, cb.x, cb.y);
- } else if (point.type == Lib.Modes.PathEditMode.Type.QUADRATIC_RIGHT) {
- var pb = points[i - 1].last_point;
- var ce = point.curve_end;
- var t2 = point.tangent_2;
- cr.move_to (pb.x, pb.y);
- cr.curve_to (t2.x, t2.y, ce.x, ce.y, ce.x, ce.y);
- } else if (point.type == Lib.Modes.PathEditMode.Type.CUBIC_SINGLE) {
- var cb = point.curve_begin;
- var t1 = point.tangent_1;
- var t2 = point.tangent_2;
- var ce = point.curve_end;
- cr.move_to (cb.x, cb.y);
- cr.curve_to (t1.x, t1.y, t2.x, t2.y, ce.x, ce.y);
- } else if (point.type == Lib.Modes.PathEditMode.Type.CUBIC_DOUBLE) {
- var pb = points[i - 1].last_point;
- var cb = point.curve_begin;
- var t1 = point.tangent_1;
- var t2 = point.tangent_2;
- var ce = point.curve_end;
- cr.curve_to (pb.x, pb.y, t1.x, t1.y, cb.x, cb.y);
- cr.curve_to (cb.x, cb.y, t2.x, t2.y, ce.x, ce.y);
- }
- }
-
- if (close) {
- cr.line_to (points[0].line_end.x, points[0].line_end.y);
- }
-
- cr.restore ();
- }
-}
diff --git a/src/Drawables/DrawableRect.vala b/src/Drawables/DrawableRect.vala
deleted file mode 100644
index b875f05b0..000000000
--- a/src/Drawables/DrawableRect.vala
+++ /dev/null
@@ -1,139 +0,0 @@
-/**
- * Copyright (c) 2019-2021 Alecaddd (https://alecaddd.com)
- *
- * This file is part of Akira.
- *
- * Akira 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.
-
- * Akira 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 Akira. If not, see .
- *
- * Authored by: Martin "mbfraga" Fraga
- *
- * Parts of this code are taken from GooCanvas
- */
-
-/*
- * Drawable for rects.
- */
-public class Akira.Drawables.DrawableRect : Drawable {
- public DrawableRect (double tl_x, double tl_y, double width, double height) {
- this.center_x = tl_x + width / 2.0;
- this.center_y = tl_y + height / 2.0;
- this.width = width;
- this.height = height;
- }
-
- public override void simple_create_path (Cairo.Context context) {
- rect_path (context, this);
- }
-
- public static void rect_path (Cairo.Context context, Drawable drawable) {
- if (drawable.has_radius) {
- //path_impl1 (cr);
- rounded_rect_path (context, drawable);
- return;
- }
-
- var w = drawable.width;
- var h = drawable.height;
- var x = drawable.center_x - w / 2.0;
- var y = drawable.center_y - h / 2.0;
- context.rectangle (x, y, w, h);
- }
-
- public static void rounded_rect_path (Cairo.Context context, Drawable drawable) {
- var w = drawable.width;
- var h = drawable.height;
-
- // aspect_ratio yet unused
- var aspect_ratio = 1.0;
- double rtl = drawable.radius_tl / aspect_ratio;
- double rtr = drawable.radius_tr / aspect_ratio;
- double rbl = drawable.radius_bl / aspect_ratio;
- double rbr = drawable.radius_br / aspect_ratio;
-
- double r_top = rtl + rtr;
- double r_bot = rbl + rbr;
- double r_right = rtr + rbr;
- double r_left = rtl + rbl;
-
- if (r_top > 0) {
- rtr = double.min (rtr, rtr / r_top * w);
- rtl = double.min (rtl, rtl / r_top * w);
- }
-
- if (r_bot > 0) {
- rbr = double.min (rbr, rbr / r_bot * w);
- rbl = double.min (rbl, rbl / r_bot * w);
- }
-
- if (r_left > 0) {
- rtl = double.min (rtl, rtl / r_left * h);
- rbl = double.min (rbl, rbl / r_left * h);
- }
-
- if (r_right > 0) {
- rtr = double.min (rtr, rtr / r_right * h);
- rbr = double.min (rbr, rbr / r_right * h);
- }
-
-
- var x = drawable.center_x - w / 2.0;
- var y = drawable.center_y - h / 2.0;
- var degrees = GLib.Math.PI / 180.0;
-
- // Add top-right
- if (rtr > 0) {
- context.arc (x + w - rtr, y + rtr, rtr, -90 * degrees, 0);
- } else {
- context.move_to (x + w, y);
- }
-
- if (rbr > 0) {
- // Add bottom-right
- context.arc (x + w - rbr, y + h - rbr, rbr, 0, 90 * degrees);
- } else {
- context.line_to (x + w, y + h);
- }
-
- if (rbl > 0) {
- // Add bottom-left
- context.arc (x + rbl, y + h - rbl, rbl, 90 * degrees, 180 * degrees);
- } else {
- context.line_to (x, y + h);
- }
-
- if (rtl > 0) {
- // Add top-left
- context.arc (x + rtl, y + rtl, rtl, 180 * degrees, 270 * degrees);
- } else {
- context.line_to (x, y);
- }
-
- context.close_path ();
- }
-
- //public override void simple_update (Cairo.Context cr) {
- // /* We can quickly compute the bounds as being just the rectangle's size
- // plus half the line width around each edge.
- // For now we keep it as the full width to avoid weird clipping issues*/
- // var half_line_width = get_line_width (); // / 2;
-
- // var x = center_x - width / 2.0;
- // var y = center_y - height / 2.0;
-
- // bounds.left = x - half_line_width;
- // bounds.top = y - half_line_width;
- // bounds.right = x + width + half_line_width;
- // bounds.bottom = y + height + half_line_width;
- //}
-}
diff --git a/src/Drawables/DrawableText.vala b/src/Drawables/DrawableText.vala
deleted file mode 100644
index ae5925568..000000000
--- a/src/Drawables/DrawableText.vala
+++ /dev/null
@@ -1,123 +0,0 @@
-/**
- * Copyright (c) 2019-2021 Alecaddd (https://alecaddd.com)
- *
- * This file is part of Akira.
- *
- * Akira 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.
-
- * Akira 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 Akira. If not, see .
- *
- * Authored by: Martin "mbfraga" Fraga
- *
- * Parts of this code are taken from GooCanvas
- */
-
-/*
- * Drawable for rects.
- */
-public class Akira.Drawables.DrawableText : Drawable {
-
- public DrawableText (double tl_x, double tl_y, double width, double height, string text) {
- this.center_x = tl_x + width / 2.0;
- this.center_y = tl_y + height / 2.0;
- this.width = width;
- this.height = height;
- this.label = text;
- }
-
- public override void simple_create_path (Cairo.Context context) {
- var w = width;
- var h = height;
- var x = center_x - w / 2.0;
- var y = center_y - h / 2.0;
-
-
- context.rectangle (x, y, w, h);
- }
-
- public override void paint (Cairo.Context context, Geometry.Rectangle target_bounds, double scale, Drawable.DrawType draw_type) {
- // Simple bounds check
- if (bounds.left > target_bounds.right || bounds.right < target_bounds.left
- || bounds.top > target_bounds.bottom || bounds.bottom < target_bounds.top) {
- return;
- }
-
- context.save ();
- context.transform (transform);
- context.set_source_rgba (0.0, 0.0, 0.0, 1.0);
- draw_text (context, scale);
- context.restore ();
-
- context.new_path ();
-
- is_drawn = true;
- }
-
- private void draw_text (Cairo.Context context, double scale) {
- var m = 0;//label_margin (scale);
-
- var w = bounds.width - m * 2;
- var h = bounds.height - m * 2;
- var x = center_x - w / 2.0;
- var y = center_y - h / 2.0;
-
- if (w <= 0 || h <= 0) {
- return;
- }
-
- Cairo.Matrix global_transform = context.get_matrix ();
- var tr = transform;
- context.set_matrix (tr);
-
- var layout = create_pango_layout (context, label, w, scale, null);
- context.set_matrix (global_transform);
- context.rectangle (x, y, w, h);
- context.clip ();
- context.move_to (x, y);
- Pango.cairo_show_layout (context, layout);
- }
-
- private static Pango.Layout create_pango_layout (
- Cairo.Context context,
- string text,
- double layout_width,
- double scale,
- double* extent_width
- ) {
- var layout = Pango.cairo_create_layout (context);
- var pango_context = layout.get_context ();
-
- if (layout_width > 0) {
- layout.set_width ( (int)(layout_width * Pango.SCALE));
- }
-
- layout.set_text (text, -1);
-
- // Load font description
- var desc = new Pango.FontDescription ();
- desc.set_family ("Open Sans");
- desc.set_size ((int) (10 * Pango.SCALE));
- layout.set_font_description (desc);
-
- // Load hint metrics
-
- var font_options = new Cairo.FontOptions ();
- font_options.set_hint_metrics (Cairo.HintMetrics.DEFAULT);
- Pango.cairo_context_set_font_options (pango_context, font_options);
-
- //layout.set_alignment (Pango.Alignment.LEFT);
- //layout.set_ellipsize (Pango.EllipsizeMode.END);
- layout.set_wrap (Pango.WrapMode.WORD);
- return layout;
- }
-
-}
diff --git a/src/FileFormat/AkiraFile.vala b/src/FileFormat/AkiraFile.vala
deleted file mode 100644
index d4b0e54ec..000000000
--- a/src/FileFormat/AkiraFile.vala
+++ /dev/null
@@ -1,178 +0,0 @@
-/*
- * Copyright (c) 2019-2020 Alecaddd (https://alecaddd.com)
- *
- * This file is part of Akira.
- *
- * Akira 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.
-
- * Akira 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 Akira. If not, see .
- *
- * Authored by: Felipe Escoto
- * Authored by: Alessandro "Alecaddd" Castellani
- */
-
-public class Akira.FileFormat.AkiraFile : Akira.FileFormat.ZipArchiveHandler {
- public weak Akira.Window window { get; construct; }
-
- public File pictures_folder { get; private set; }
- public File thumbnails_folder { get; private set; }
-
- public bool overwrite = false;
-
- private File content_file { get; set; }
- public string path {
- owned get {
- return opened_file.get_parent ().get_path () + "/" + opened_file.get_basename ();
- }
- }
-
- public AkiraFile (File _gzipped_file, Akira.Window window) {
- Object (opened_file: _gzipped_file.dup (), window: window);
- }
-
- public void load_file () {
- try {
- open_archive ();
-
- var content_json = get_content_as_json (content_file);
-
- FileFormat.JsonDeserializer.json_object_to_world (content_json, window);
-
- update_recent_list.begin ();
-
- debug ("Version from file: %s", content_json.get_string_member ("version"));
- } catch (Error e) {
- error ("Could not load file: %s", e.message);
- }
- }
-
- public void save_file () {
- try {
- //save_images.begin ();
-
- var world_json = FileFormat.JsonSerializer.world_to_json_node (window);
- write_content_to_file (content_file, FileFormat.JsonSerializer.json_to_string (world_json, true));
-
- write_to_archive ();
- update_recent_list.begin ();
- } catch (Error e) {
- warning ("%s\n", e.message);
- }
- }
-
- public void close () {
- try {
- clean ();
- } catch (Error e) {
- warning ("%s\n", e.message);
- }
- }
-
- public override void prepare () {
- base.prepare ();
-
- var base_path = unarchived_location.get_path ();
- pictures_folder = File.new_for_path (Path.build_filename (base_path, "Pictures"));
- thumbnails_folder = File.new_for_path (Path.build_filename (base_path, "Thumbnails"));
-
- make_dir (pictures_folder);
- make_dir (thumbnails_folder);
-
- content_file = File.new_for_path (Path.build_filename (base_path, "content.json"));
-
- make_file (content_file);
- }
-
- /**
- * Update the GSettings array of recently opened files.
- */
- private async void update_recent_list () {
- string[] array = {};
- // Add the last opened file always on top.
- array += path;
-
- for (var i = 0; i <= settings.recently_opened.length; i++) {
- // Skip if the record is empty.
- if (settings.recently_opened[i] == null) {
- continue;
- }
-
- // If the file doesn't exist anymore, remove it from the list.
- var file = File.new_for_path (settings.recently_opened[i]);
- if (!file.query_exists ()) {
- continue;
- }
-
- // Don't store more than 10 files.
- if (i >= 9) {
- break;
- }
-
- // If the same file was already in the list, don't save it again.
- if (path == settings.recently_opened[i]) {
- continue;
- }
-
- array += settings.recently_opened[i];
- }
-
- settings.set_strv ("recently-opened", array);
-
- window.app.update_recent_files_list ();
- }
-
- /**
- * Save all the images used in the Canvas and make a copy in the Pictures folder.
- */
- // public async void save_images () {
- // // Clear potential leftover images if we're overwriting an existing file.
- // if (overwrite) {
- // try {
- // Dir dir = Dir.open (pictures_folder.get_path (), 0);
- // string? name = null;
- // while ((name = dir.read_name ()) != null) {
- // var file = File.new_for_path (Path.build_filename (pictures_folder.get_path (), name));
- // file_collector.mark_for_deletion (file);
- // }
- // } catch (FileError err) {
- // stderr.printf (err.message);
- // }
- // overwrite = false;
- // }
-
- // foreach (var image in window.items_manager.images) {
- // var image_file = File.new_for_path (
- // Path.build_filename (pictures_folder.get_path (), image.manager.filename)
- // );
-
- // // Copy the file if it doesn't exist, or increase the reference count.
- // if (!image_file.query_exists ()) {
- // copy_image (image.manager.file, image_file);
- // continue;
- // }
- // }
- // }
-
- /**
- * Decrease the reference count to an existing image, which will cause its
- * deletion if the count reaches 0.
- */
- public async void remove_image (string filename) {
- var image_file = File.new_for_path (
- Path.build_filename (pictures_folder.get_path (), filename)
- );
-
- if (image_file.query_exists ()) {
- file_collector.unref_file (image_file);
- }
- }
-}
diff --git a/src/FileFormat/FileManager.vala b/src/FileFormat/FileManager.vala
deleted file mode 100644
index 5754d1902..000000000
--- a/src/FileFormat/FileManager.vala
+++ /dev/null
@@ -1,130 +0,0 @@
-/*
-* Copyright (c) 2020 Alecaddd (https://alecaddd.com)
-*
-* This file is part of Akira.
-*
-* Akira 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.
-
-* Akira 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 Akira. If not, see .
-*
-* Authored by: Alessandro "Alecaddd" Castellani
-*/
-
-public class Akira.FileFormat.FileManager : Object {
- public weak Akira.Window window { get; construct; }
-
- public FileManager (Akira.Window window) {
- Object (
- window: window
- );
- }
-
- // Save file.
- public void save_file () {
- // Check if we already have a file open to save or save a new one.
- if (window.akira_file != null) {
- window.akira_file.save_file ();
- window.event_bus.file_saved (null);
- return;
- }
-
- save_file_as ();
- }
-
- // Save as.
- public void save_file_as () {
- var dialog = new Gtk.FileChooserNative (
- _("Save Akira file"), window,
- Gtk.FileChooserAction.SAVE,
- _("Save"),
- _("Cancel"));
-
- dialog.set_do_overwrite_confirmation (true);
- add_filters (dialog);
- dialog.set_modal (true);
- if (window.akira_file != null) {
- var file = File.new_for_path (window.akira_file.path);
- try {
- dialog.set_file (file);
- }
- catch (GLib.Error error) {
- info ("%s\n", error.message);
- }
- }
-
- dialog.response.connect ((response_id) => save_file_as_response (dialog, response_id));
- dialog.show ();
- }
-
- private void add_filters (Gtk.FileChooserNative chooser) {
- Gtk.FileFilter filter = new Gtk.FileFilter ();
- filter.add_pattern ("*.akira");
- filter.set_filter_name (_("Akira files"));
- chooser.add_filter (filter);
-
- filter = new Gtk.FileFilter ();
- filter.add_pattern ("*");
- filter.set_filter_name (_("All files"));
- chooser.add_filter (filter);
- }
-
- private void save_file_as_response (Gtk.FileChooserNative dialog, int response_id) {
- bool overwrite = false;
-
- switch (response_id) {
- case Gtk.ResponseType.ACCEPT:
- File file;
- var save_file = dialog.get_file ();
- var path = save_file.get_path ();
- if (path.has_suffix (".akira")) {
- file = save_file;
- overwrite = true;
- } else {
- file = File.new_for_path (path + ".akira");
- }
- window.save_new_file (file, overwrite);
- window.event_bus.file_saved (dialog.get_current_name ());
- break;
- }
- dialog.destroy ();
- }
-
- // Open file.
- public void open_file () {
- var dialog = new Gtk.FileChooserNative (_("Open Akira file"), window,
- Gtk.FileChooserAction.OPEN,
- _("Open"), _("Cancel"));
-
- add_filters (dialog);
- dialog.local_only = true;
- dialog.select_multiple = false;
- dialog.response.connect ((response_id) => open_file_response (dialog, response_id));
- dialog.show ();
- }
-
- private void open_file_response (Gtk.FileChooserNative dialog, int response_id) {
- switch (response_id) {
- case Gtk.ResponseType.ACCEPT:
- case Gtk.ResponseType.OK:
- File[] files = {};
- files += dialog.get_file ();
- window.app.open (files, "");
- info ("opened: %s\n", (dialog.get_filename ()));
- break;
-
- case Gtk.ResponseType.CANCEL:
- info ("Cancelled: FileChooserAction.OPEN\n");
- break;
- }
- dialog.destroy ();
- }
-}
diff --git a/src/FileFormat/JsonDeserializer.vala b/src/FileFormat/JsonDeserializer.vala
deleted file mode 100644
index e1158bae5..000000000
--- a/src/FileFormat/JsonDeserializer.vala
+++ /dev/null
@@ -1,128 +0,0 @@
-/*
- * Copyright (c) 2020-2021 Alecaddd (https://alecaddd.com)
- *
- * This file is part of Akira.
- *
- * Akira 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.
-
- * Akira 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 Akira. If not, see .
- *
- * Authored by: Alessandro "Alecaddd" Castellani
- */
-
-public class Akira.FileFormat.JsonDeserializer {
- /*
- * Deserialize a Json.Node and apply it to the current world state.
- * This deserializes a node, which is symmetric with the output of JsonSerializer.
- */
- public static void json_node_to_world (Json.Node node, Akira.Window window, bool items_only = false) {
- var obj = node.get_object ();
- if (obj != null) {
- json_object_to_world (obj, window, items_only);
- }
- }
-
- /*
- * Deserialize a Json.Node and apply it to the current world state.
- */
- public static void json_object_to_world (Json.Object obj, Akira.Window window, bool items_only = false) {
- var view_canvas = window.main_window.main_view_canvas.canvas;
-
- // Set the canvas to simulate a click + holding state to avoid triggering
- // redrawing methods connected to that state.
- view_canvas.holding = true;
-
-
- if (!items_only) {
- load_window_states (window, obj);
- }
-
- deserialize_model (window.main_window.main_view_canvas.canvas, obj);
-
- // Reset the holding state at the end of it.
- view_canvas.holding = false;
- }
-
- /*
- * Deserialize window states and apply them to the window.
- */
- private static void load_window_states (Akira.Window window, Json.Object obj) {
- window.event_bus.adjust_zoom (obj.get_double_member ("scale"), true, null);
- window.main_window.main_view_canvas.main_scroll.hadjustment.value = obj.get_double_member ("hadjustment");
- window.main_window.main_view_canvas.main_scroll.vadjustment.value = obj.get_double_member ("vadjustment");
- }
-
- /*
- * Deserialize the model.
- */
- private static void deserialize_model (Lib.ViewCanvas view_canvas, Json.Object obj) {
- var roots = obj.get_member ("roots");
- if (roots == null) {
- // bad file
- assert (false);
- return;
- }
-
- foreach (unowned Json.Node root in roots.get_array ().get_elements ()) {
- deserialize_node (view_canvas, root.get_object (), Lib.Items.Model.ORIGIN_ID);
- }
-
- view_canvas.items_manager.compile_model ();
- }
-
- /*
- * Deserialize a specific node, recursive.
- */
- private static void deserialize_node (Lib.ViewCanvas view_canvas, Json.Object node_obj, int group_id) {
- if (!node_obj.has_member ("type")) {
- assert (false);
- return;
- }
-
- int new_id = -1;
- var type = node_obj.get_string_member ("type");
-
- var components_json = node_obj.get_member ("components");
- var components = Lib.Components.Components.deserialize (components_json);
-
- Lib.Items.ModelInstance? new_inst = null;
- if (type == "rect") {
- new_inst = new Lib.Items.ModelInstance (-1, new Lib.Items.ModelTypeRect ());
- } else if (type == "ellipse") {
- new_inst = new Lib.Items.ModelInstance (-1, new Lib.Items.ModelTypeEllipse ());
- } else if (type == "group") {
- new_inst = new Lib.Items.ModelInstance (-1, new Lib.Items.ModelTypeGroup ());
- } else if (type == "artboard") {
- new_inst = new Lib.Items.ModelInstance (-1, new Lib.Items.ModelTypeArtboard ());
- } else if (type == "path") {
- new_inst = new Lib.Items.ModelInstance (-1, new Lib.Items.ModelTypePath ());
- } else if (type == "text") {
- new_inst = new Lib.Items.ModelInstance (-1, new Lib.Items.ModelTypeText ());
- }
- else {
- // Unknown type
- assert (false);
- return;
- }
-
- new_inst.components = components;
-
- new_id = view_canvas.items_manager.add_item_to_group (group_id, new_inst, true);
-
- var children = node_obj.get_member ("children");
- if (children != null) {
- foreach (unowned Json.Node child in children.get_array ().get_elements ()) {
- deserialize_node (view_canvas, child.get_object (), new_id);
- }
- }
- }
-}
diff --git a/src/FileFormat/JsonItemSerializer.vala b/src/FileFormat/JsonItemSerializer.vala
deleted file mode 100644
index 72e19b3b1..000000000
--- a/src/FileFormat/JsonItemSerializer.vala
+++ /dev/null
@@ -1,67 +0,0 @@
-/**
- * Copyright (c) 2019-2021 Alecaddd (https://alecaddd.com)
- *
- * This file is part of Akira.
- *
- * Akira 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.
-
- * Akira 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 Akira. If not, see .
- *
- * Authored by: Felipe Escoto
- * Authored by: Alessandro "Alecaddd" Castellani
- */
-
-/**
- * Converts an item into a JSON Object, converting all the child attributes to string.
- */
-public class Akira.FileFormat.JsonItemSerializer {
-
- /*
- * Serialize an item and return its corresponding Json.Node.
- */
- public static void serialize_node (Akira.Lib.Items.ModelNode node, ref Json.Builder builder) {
- builder.begin_object ();
-
- // serialize type
- {
- builder.set_member_name ("type");
- builder.add_string_value (node.instance.type.name_id);
- }
-
- // serialize components
- node.instance.components.serialize (ref builder);
-
- // serialize children
- if (node.instance.children != null && node.instance.children.length != 0) {
- serialize_children (node, ref builder);
- }
-
- builder.end_object ();
- }
-
- /*
- * Serialize all children of a node recursively.
- */
- public static void serialize_children (Akira.Lib.Items.ModelNode node, ref Json.Builder builder) {
- builder.set_member_name ("children");
-
- {
- builder.begin_array ();
-
- foreach (unowned var child in node.children.data) {
- serialize_node (child, ref builder);
- }
-
- builder.end_array ();
- }
- }
-}
diff --git a/src/FileFormat/JsonSerializer.vala b/src/FileFormat/JsonSerializer.vala
deleted file mode 100644
index 72fe6a79a..000000000
--- a/src/FileFormat/JsonSerializer.vala
+++ /dev/null
@@ -1,86 +0,0 @@
-/*
- * Copyright (c) 2020 Alecaddd (https://alecaddd.com)
- *
- * This file is part of Akira.
- *
- * Akira 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.
-
- * Akira 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 Akira. If not, see .
- *
- * Authored by: Alessandro "Alecaddd" Castellani
- */
-
-public class Akira.FileFormat.JsonSerializer {
-
- /*
- * Converts the world (window, and canvas item information) to a Json.Node.
- * Use this and json_to_string to save Akira's file state.
- */
- public static Json.Node world_to_json_node (Akira.Window window, bool items_only = false) {
- var builder = new Json.Builder ();
- builder.begin_object ();
-
- if (!items_only) {
- serialize_window_state (window, ref builder);
- }
-
- var view_canvas = window.main_window.main_view_canvas.canvas;
-
- // Convert Model to JSON.
- serialize_model (view_canvas.items_manager.item_model, ref builder);
-
- builder.end_object ();
-
- return builder.get_root ();
- }
-
- /*
- * Converts a Json.Node to a string
- */
- public static string json_to_string (Json.Node node, bool pretty) {
- var generator = new Json.Generator ();
- generator.pretty = pretty;
- generator.set_root (node);
- return generator.to_data (null);
- }
-
- /*
- * Serialize window states to the builder.
- */
- public static void serialize_window_state ( Akira.Window window, ref Json.Builder builder) {
- // Save the current version of Akira.
- builder.set_member_name ("version");
- builder.add_string_value (Constants.VERSION);
-
- // Save the current Canvas status.
- builder.set_member_name ("scale");
- builder.add_double_value (window.main_window.main_view_canvas.canvas.scale);
- builder.set_member_name ("hadjustment");
- builder.add_double_value (window.main_window.main_view_canvas.main_scroll.hadjustment.value);
- builder.set_member_name ("vadjustment");
- builder.add_double_value (window.main_window.main_view_canvas.main_scroll.vadjustment.value);
- }
-
- /*
- * Serialize canvas artboards to the builder.
- */
- public static void serialize_model (Akira.Lib.Items.Model item_model, ref Json.Builder builder) {
- var origin = item_model.node_from_id (Akira.Lib.Items.Model.ORIGIN_ID);
- builder.set_member_name ("roots");
- builder.begin_array ();
- foreach (var root in origin.children.data) {
- JsonItemSerializer.serialize_node (root, ref builder);
- }
-
- builder.end_array ();
- }
-}
diff --git a/src/FileFormat/ZipArchiveHandler.vala b/src/FileFormat/ZipArchiveHandler.vala
deleted file mode 100644
index 56151c1f3..000000000
--- a/src/FileFormat/ZipArchiveHandler.vala
+++ /dev/null
@@ -1,460 +0,0 @@
-/*
- * Copyright (c) 2019-2020 Alecaddd (https://alecaddd.com)
- *
- * This file is part of Akira.
- *
- * Akira 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.
-
- * Akira 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 Akira. If not, see .
- *
- * Authored by: Felipe Escoto
- * Authored by: Alessandro "Alecaddd" Castellani
- */
-
-public class Akira.FileFormat.ZipArchiveHandler : GLib.Object {
- // Prefix to be added at the beginning of the folder name when a gzipped file is opened.
- // Should start with a period to hide the folder by default.
- private const string UNARCHIVED_PREFIX = ".~lock.akira.";
-
- /**
- * The GZipped File that opened this archive
- */
- public File opened_file { get; construct set; }
-
- /**
- * The Unzipped folder location
- */
- public File unarchived_location { get; private set; }
-
- /**
- * Creates a zipped file for archive purposes
- */
- public ZipArchiveHandler (File gzipped_file) {
- Object (opened_file: gzipped_file.dup ());
- }
-
- public FileCollector file_collector { get; private set; }
-
- construct {
- var parent_folder = opened_file.get_parent ().get_path ();
- unarchived_location = File.new_for_path (
- Path.build_filename (parent_folder, UNARCHIVED_PREFIX + opened_file.get_basename ()));
-
- file_collector = new FileCollector (unarchived_location);
- }
-
- protected static string get_content_from_file (File file) {
- try {
- string data;
- FileUtils.get_contents (file.get_path (), out data);
-
- return data;
- } catch (Error e) {
- warning (e.message);
- return "";
- }
- }
-
- protected static Json.Object get_content_as_json (File file) {
- try {
- var parser = new Json.Parser ();
- parser.load_from_data (get_content_from_file (file));
-
- return parser.get_root ().get_object ();
- } catch (Error e) {
- return new Json.Object ();
- }
- }
-
- protected static void write_content_to_file (File file, string data) {
- try {
- FileUtils.set_contents (file.get_path (), data);
- } catch (Error e) {
- warning (e.message);
- }
- }
-
- /**
- * Helper function to create a directory if it does not exist
- */
- protected void make_dir (File file) {
- if (!file.query_exists ()) {
- try {
- file.make_directory_with_parents ();
- } catch (Error e) {
- warning ("%s\n", e.message);
- }
- }
- }
-
- /**
- * Helper function to create a file if it does not exist
- */
- protected void make_file (File file) {
- if (!file.query_exists ()) {
- try {
- file.create (FileCreateFlags.REPLACE_DESTINATION);
- } catch (Error e) {
- warning ("%s\n", e.message);
- }
- }
- }
-
- /**
- * Used to create all the files needed for this if they do not exist.
- *
- * Can be overwritten to add your own files and folders for the internal
- * file structure you require. If overwritten, make sure to call base.prepare ()
- */
- public virtual void prepare () {
- var parent_folder = opened_file.get_parent ();
- make_dir (parent_folder);
- make_file (opened_file);
- make_dir (unarchived_location);
- }
-
- /**
- * Used to check if the file was already extracted. Use this to handle recovery for your users.
- */
- protected virtual bool is_opened () {
- return unarchived_location.query_exists ();
- }
-
- /**
- * Extracts the contents of the file to unarchived_location
- */
- protected void open_archive () throws Error {
- extract (opened_file, unarchived_location);
- }
-
- /**
- * Saves content from the unzipped location to the GZipped file.
- */
- protected void write_to_archive () throws Error {
- // Clear files marked before archiving anything
- file_collector.delete_files_marked_for_deletion ();
-
- // Saving to a temp file first to avoid dataloss on a crash
- var tmp_file = File.new_for_path (opened_file.get_path () + ".tmp");
-
- compress (unarchived_location, tmp_file);
- if (opened_file.query_exists ()) {
- opened_file.delete ();
- }
-
- FileUtils.rename (tmp_file.get_path (), opened_file.get_path ());
- }
-
- /**
- * Removes all files from the unarchived location. Should run before closing the program to cleanup temp files
- */
- protected void clean () throws Error {
- // Checking if it contains the prefix as a safety to prevent errors
- if (is_opened () && unarchived_location.get_path ().contains (UNARCHIVED_PREFIX)) {
- delete_recursive (unarchived_location);
- unarchived_location.delete ();
- }
- }
-
- public File get_file_from_basename (File location, string basename) {
- var path = Path.build_filename (location.get_path (), basename);
- return File.new_for_path (path);
- }
-
- /**
- * Gets a random file inside the archive at the location specified
- * using a guid-like name.
- *
- * @param location - Location inside of the archive where the file will live at.
- * @param extension - The extension the file created will have.
- * @param format - The format for the file. The character "?" will be replaced
- * with a random character. For example, XXXX-XX can become a5b7-Df.
- * The default is "XXXXXXXX-XXXX-XX".
- */
- public File get_random_file_name (File location, string extension, string format = "XXXXXXXX-XXXX-XX") {
- do {
- var path = Path.build_filename (location.get_path (), get_guid (format) + "." + extension);
-
- var file = File.new_for_path (path);
- if (!file.query_exists ()) {
- return file;
- }
- } while (true);
- }
-
- private Rand? rand = new Rand ();
- private const string GUID_CHARS = "0123456789ABCDEFabcdef";
-
- private string get_guid (string format) {
- var guid = new StringBuilder.sized (format.length);
- int format_length = format.length;
-
- for (int i = 0; i < format_length; i++) {
- switch (format[i]) {
- case 'X':
- var r = rand.next_int () % GUID_CHARS.length;
- guid.append_c (GUID_CHARS[r]);
- break;
- default:
- guid.append_c (format[i]);
- break;
- }
- }
-
- return guid.str;
- }
-
- // DANGEROUS, use with caution
- private void delete_recursive (File file) {
- try {
- var enumerator = file.enumerate_children (FileAttribute.STANDARD_NAME, 0);
-
- FileInfo file_info;
- while ((file_info = enumerator.next_file ()) != null) {
- var current_file = file.resolve_relative_path (file_info.get_name ());
-
- if (file_info.get_file_type () == FileType.DIRECTORY) {
- delete_recursive (current_file);
- }
-
- current_file.delete ();
- }
- } catch (Error e) {
- critical ("Error: %s\n", e.message);
- }
- }
-
- // Extracts all contents of the gzip file to the location
- private static void extract (File gzipped_file, File location) throws Error {
- Archive.ExtractFlags flags;
- flags = Archive.ExtractFlags.TIME;
- flags |= Archive.ExtractFlags.PERM;
- flags |= Archive.ExtractFlags.ACL;
- flags |= Archive.ExtractFlags.FFLAGS;
-
- Archive.Read archive = new Archive.Read ();
- archive.support_format_all ();
- archive.support_filter_all ();
-
- Archive.WriteDisk extractor = new Archive.WriteDisk ();
- extractor.set_options (flags);
- extractor.set_standard_lookup ();
-
- if (archive.open_filename (gzipped_file.get_path (), 10240) != Archive.Result.OK) {
- throw new FileError.FAILED (
- "Error opening %s: %s (%d)", gzipped_file.get_path (), archive.error_string (), archive.errno ()
- );
- }
-
- unowned Archive.Entry entry;
- Archive.Result last_result;
-
- while ((last_result = archive.next_header (out entry)) == Archive.Result.OK) {
- entry.set_perm (0644);
- entry.set_pathname (Path.build_filename (location.get_path (), entry.pathname ()));
-
- if (extractor.write_header (entry) != Archive.Result.OK) {
- continue;
- }
-
- Posix.off_t offset;
- uint8[] buffer;
- while (archive.read_data_block (out buffer, out offset) == Archive.Result.OK) {
- if (extractor.write_data_block (buffer, offset) != Archive.Result.OK) {
- break;
- }
- }
- }
-
- if (last_result != Archive.Result.EOF) {
- critical ("Error: %s (%d)", archive.error_string (), archive.errno ());
- }
- }
-
- // Compresses all files recursibly from location to the gzipped file.
- private static void compress (File location, File gzipped_file) throws Error {
- var to_write = File.new_for_path (gzipped_file.get_path ());
- if (to_write.query_exists ()) {
- to_write.delete ();
- }
-
- to_write.create (FileCreateFlags.REPLACE_DESTINATION);
-
- Archive.Write archive = new Archive.Write ();
- archive.set_format_zip ();
- archive.open_filename (to_write.get_path ());
-
- add_to_archive_recursive (location, location, archive);
-
- if (archive.close () != Archive.Result.OK) {
- critical ("Error : %s (%d)", archive.error_string (), archive.errno ());
- }
- }
-
- private static void add_to_archive_recursive (File initial_folder, File folder, Archive.Write archive) {
- try {
- var enumerator = folder.enumerate_children (FileAttribute.STANDARD_NAME, 0);
-
- FileInfo current_info;
- while ((current_info = enumerator.next_file ()) != null) {
- var current_file = folder.resolve_relative_path (current_info.get_name ());
-
- if (current_info.get_file_type () == FileType.DIRECTORY) {
- add_to_archive_recursive (initial_folder, current_file, archive);
- } else {
- GLib.FileInfo file_info = current_file.query_info (GLib.FileAttribute.STANDARD_SIZE,
- GLib.FileQueryInfoFlags.NONE);
-
- FileInputStream input_stream = current_file.read ();
- DataInputStream data_input_stream = new DataInputStream (input_stream);
-
- // Add an entry to the archive
- Archive.Entry entry = new Archive.Entry ();
- entry.set_pathname (initial_folder.get_relative_path (current_file));
- entry.set_size ((Archive.int64_t) file_info.get_size ());
- entry.set_filetype (Archive.FileType.IFREG);
- entry.set_perm (0644);
-
- if (archive.write_header (entry) != Archive.Result.OK) {
- critical (
- "Error writing '%s': %s (%d)",
- current_file.get_path (),
- archive.error_string (),
- archive.errno ()
- );
- return;
- }
-
- // Add the actual content of the file
- size_t bytes_read;
- uint8[] buffer = new uint8[64];
- while (data_input_stream.read_all (buffer, out bytes_read)) {
- if (bytes_read <= 0) {
- break;
- }
-
- archive.write_data (buffer[0:bytes_read]);
- }
- }
- }
- } catch (Error e) {
- critical ("Error: %s\n", e.message);
- }
- }
-
- public virtual void copy_image (GLib.File old_file, GLib.File new_file) {
- try {
- old_file.copy (new_file, 0, null, (current_num_bytes, total_num_bytes) => {
- // Report copy-status:
- print ("%" + int64.FORMAT + " bytes of %" + int64.FORMAT + " bytes copied.\n",
- current_num_bytes, total_num_bytes);
- });
- file_collector.ref_file (new_file);
- } catch (Error e) {
- print ("Error: %s\n", e.message);
- }
- }
-
-
- /**
- * Takes care of the reference counting for files inside the archive.
- * This allows to multiple objects to reference the same file, and only
- * mark the file for deletion if no other object is using it.
- */
- protected class FileCollector {
- private unowned File unarchived_location;
- private Gee.HashMap for_deletion;
- private Gee.HashMap ref_counter;
-
- public FileCollector (File _unarchived_location) {
- unarchived_location = _unarchived_location;
-
- for_deletion = new Gee.HashMap ();
- ref_counter = new Gee.HashMap ();
- }
-
- /**
- * Gets the number of times a file is being used
- */
- public int file_references (File file) {
- var file_basename = file.get_basename ();
- return ref_counter.has_key (file_basename) ? ref_counter.get (file_basename) : 0;
- }
-
- /**
- * Adds 1 to the ref counter for that file.
- */
- public void ref_file (File file) {
- var file_basename = file.get_basename ();
- if (for_deletion.has_key (file_basename)) {
- unmark_for_deletion (file);
- }
-
- var ref_count = file_references (file);
- ref_counter.set (file_basename, ref_count + 1);
- print ("File ref %d %s \n", ref_count + 1, file.get_basename ());
- }
-
- /**
- * Subtracts 1 on the ref counter for that file. If set to 0, the file will be marked for deletion
- */
- public void unref_file (File file) {
- var file_basename = file.get_basename ();
-
- var ref_count = file_references (file);
- if (ref_count > 0) {
- ref_counter.set (file_basename, ref_count - 1);
-
- if (ref_count == 1) {
- mark_for_deletion (file);
- }
- print ("File unref %d %s \n", ref_count - 1, file.get_basename ());
- }
- }
-
- /**
- * Marks a file to be deleted and not saved to the archive. Said files will be deleted
- * when write_to_archive runs or when you manually call "delete_files_marked_for_deletion".
- *
- * Files will only be added to the list when they are inside the unarchived location
- */
- public void mark_for_deletion (File file) {
- if (file.get_path ().contains (unarchived_location.get_path ())) {
- for_deletion.set (file.get_basename (), file);
- print ("Marked for deletion: %s\n", file.get_basename ());
- }
- }
-
- /**
- * Unmarks a file previously marked for deletion.
- */
- public void unmark_for_deletion (File file) {
- for_deletion.unset (file.get_basename ());
- print ("unmarked for deletion: %s\n", file.get_basename ());
- }
-
- /**
- * Deletes all files whose ref counter is set to 0, or those marked for deletion
- */
- public void delete_files_marked_for_deletion () {
- foreach (var file in for_deletion.values) {
- try {
- file.delete ();
- } catch (Error e) {
- warning ("File could not be deleted %s\n", e.message);
- }
- };
-
- for_deletion.clear ();
- }
- }
-}
diff --git a/src/Geometry/PathSegment.vala b/src/Geometry/PathSegment.vala
deleted file mode 100644
index 87767b854..000000000
--- a/src/Geometry/PathSegment.vala
+++ /dev/null
@@ -1,359 +0,0 @@
-/**
- * Copyright (c) 2022 Alecaddd (https://alecaddd.com)
- *
- * This file is part of Akira.
- *
- * Akira 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.
-
- * Akira 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 Akira. If not, see .
- *
- * Authored by: Ashish Shevale
-*/
-
-/*
- * Following is a generic structure used for storing all types of segments
- * in a path.
- * type : refers to the type of segment.
- * curve_begin : first point of a curve or end point of line.
- * tangent_1, tangent_2 : control points for controlling curves.
- * curve_end : last point of a curve
- *
- * We can create a different types of segments using this rep as
- * 1. Symmetric Bezier Curve (both control points are equi-distant from curve_begin)
- * 2. Asymmetric Bezier Curve (control points can be at different distances from curve_begin)
- * 3. Quadratic Curve (single control point) => Left handed and right handed
- * 4. Line (pretty obvious)
- * 5. Single Segment bezier curve.
- */
-public struct Akira.Geometry.PathSegment {
- public Lib.Modes.PathEditMode.Type type;
-
- // This point is used for drawing lines.
- // Store point in segment_begin to save space, but use the alias to make code readable.
- public Geometry.Point line_end {
- get {
- return curve_begin;
- }
- set {
- curve_begin = value;
- }
- }
-
- public Geometry.Point last_point {
- get {
- if (type == Lib.Modes.PathEditMode.Type.LINE) {
- return line_end;
- } else if (type == Lib.Modes.PathEditMode.Type.QUADRATIC_LEFT) {
- return curve_begin;
- }
-
- return curve_end;
- }
- }
-
- // These points are used for drawing curves.
- public Geometry.Point curve_begin;
- public Geometry.Point tangent_1;
- public Geometry.Point tangent_2;
- public Geometry.Point curve_end;
-
- // Creates new line segment.
- public PathSegment.line (Geometry.Point point) {
- type = Lib.Modes.PathEditMode.Type.LINE;
- line_end = point;
-
- // Initializing the remaining unused points allows us to
- // transform the whole segment without worrying its type.
- tangent_1 = Geometry.Point (0, 0);
- tangent_2 = Geometry.Point (0, 0);
- curve_end = Geometry.Point (0, 0);
- }
-
- // Creates new cubic bezier curve.
- public PathSegment.cubic_bezier (
- Geometry.Point curve_begin,
- Geometry.Point control_point_1,
- Geometry.Point control_point_2,
- Geometry.Point curve_end
- ) {
- type = Lib.Modes.PathEditMode.Type.CUBIC_DOUBLE;
-
- this.curve_begin = curve_begin;
- this.tangent_1 = control_point_1;
- this.tangent_2 = control_point_2;
- this.curve_end = curve_end;
- }
-
- public PathSegment.cubic_bezier_single (
- Geometry.Point curve_begin,
- Geometry.Point control_point_1,
- Geometry.Point control_point_2,
- Geometry.Point curve_end
- ) {
- type = Lib.Modes.PathEditMode.Type.CUBIC_SINGLE;
-
- this.curve_begin = curve_begin;
- this.tangent_1 = control_point_1;
- this.tangent_2 = control_point_2;
- this.curve_end = curve_end;
- }
-
- // Creates new quadratic bezier curve
- public PathSegment.quadratic_bezier_left (
- Geometry.Point curve_begin,
- Geometry.Point control_point
- ) {
- type = Lib.Modes.PathEditMode.Type.QUADRATIC_LEFT;
-
- this.curve_begin = curve_begin;
- this.tangent_1 = control_point;
-
- tangent_2 = Geometry.Point (0, 0);
- curve_end = Geometry.Point (0, 0);
- }
-
- public PathSegment.quadratic_bezier_right (
- Geometry.Point curve_end,
- Geometry.Point control_point
- ) {
- type = Lib.Modes.PathEditMode.Type.QUADRATIC_RIGHT;
-
- this.curve_end = curve_end;
- this.tangent_2 = control_point;
-
- tangent_1 = Geometry.Point (0, 0);
- curve_begin = Geometry.Point (0, 0);
- }
-
- public PathSegment copy () {
- var segment = PathSegment ();
-
- segment.type = type;
- segment.curve_begin = curve_begin;
- segment.tangent_1 = tangent_1;
- segment.tangent_2 = tangent_2;
- segment.curve_end = curve_end;
-
- return segment;
- }
-
- // Use for converting a line segment to a curve.
- // point_before and point_after are used for calculating positions of control points.
- // If point_after is not provided, create a quadratic curve
- // If it is provided, create a symmetric cubic_DOUBLE bezier curve
- public void line_to_curve (
- PathSegment? segment_before,
- PathSegment? segment_after
- ) {
- // Atleast one of the segments must be present inorder to calculate tangents.
- assert (segment_before != null && segment_after != null);
-
- // When converting to quadratic curves, this is the dist. at which tangents are placed.
- double tangent_length = 100;
- type = Lib.Modes.PathEditMode.Type.CUBIC_DOUBLE;
-
- // If we are converting the first point of the segment,
- // Make it a quadratic curve. Never occurs, but kept as safeguard.
- if (segment_before == null) {
- type = Lib.Modes.PathEditMode.Type.QUADRATIC_LEFT;
- tangent_1 = Geometry.Point (curve_begin.x - tangent_length, curve_begin.y - tangent_length);
-
- return;
- }
-
- // If last segment is being converted to curve, make it quadratic.
- if (segment_after == null) {
- type = Lib.Modes.PathEditMode.Type.QUADRATIC_LEFT;
- tangent_1 = Geometry.Point (curve_begin.x + tangent_length, curve_begin.y + tangent_length);
-
- return;
- }
-
- // For all other segments, we need to find position for tangents.
- // Following will create tangents that are parallel to CURVE_BEGIN and CURVE_END
- // to make result more appealing.
- Geometry.Point point_before, point_after;
-
- if (segment_before.type == Lib.Modes.PathEditMode.Type.LINE) {
- point_before = segment_before.line_end;
- } else {
- point_before = Geometry.Point (
- (curve_begin.x + segment_before.curve_begin.x) / 2.0,
- (curve_begin.y + segment_before.curve_begin.y) / 2.0
- );
- }
-
- if (segment_after.type == Lib.Modes.PathEditMode.Type.LINE) {
- point_after = segment_after.line_end;
- } else {
- point_after = Geometry.Point (
- (curve_begin.x + segment_after.curve_begin.x) / 2.0,
- (curve_begin.y + segment_after.curve_begin.y) / 2.0
- );
- }
-
- var mid_vector = Geometry.Point (
- (point_after.x - point_before.x) / 2.0,
- (point_after.y - point_before.y) / 2.0
- );
-
- tangent_1 = Geometry.Point (curve_begin.x - mid_vector.x, curve_begin.y - mid_vector.y);
- tangent_2 = Geometry.Point (curve_begin.x + mid_vector.x, curve_begin.y + mid_vector.y);
- curve_end = point_after;
- }
-
- // Use for converting a curve segment to a line.
- public void curve_to_line () {
- type = Lib.Modes.PathEditMode.Type.LINE;
- }
-
- public Geometry.Point get_by_type (Lib.Modes.PathEditMode.PointType ptype) {
- if (ptype == Lib.Modes.PathEditMode.PointType.LINE_END) {
- return line_end;
- }
-
- if (ptype == Lib.Modes.PathEditMode.PointType.CURVE_BEGIN) {
- return curve_begin;
- }
-
- if (ptype == Lib.Modes.PathEditMode.PointType.TANGENT_FIRST) {
- return tangent_1;
- }
-
- if (ptype == Lib.Modes.PathEditMode.PointType.TANGENT_SECOND) {
- return tangent_2;
- }
-
- if (ptype == Lib.Modes.PathEditMode.PointType.CURVE_END) {
- return curve_end;
- }
-
- assert (false);
- return Geometry.Point (0, 0);
- }
-
- public Lib.Modes.PathEditMode.PointType hit_test (Geometry.Point point, double thresh) {
- if (type == Lib.Modes.PathEditMode.Type.LINE) {
- if (Utils.GeometryMath.compare_points (line_end, point, thresh)) {
- return Lib.Modes.PathEditMode.PointType.LINE_END;
- }
- } else if (type == Lib.Modes.PathEditMode.Type.QUADRATIC_LEFT) {
- if (Utils.GeometryMath.compare_points (curve_begin, point, thresh)) {
- return Lib.Modes.PathEditMode.PointType.CURVE_BEGIN;
- }
-
- if (Utils.GeometryMath.compare_points (tangent_1, point, thresh)) {
- return Lib.Modes.PathEditMode.PointType.TANGENT_FIRST;
- }
- } else if (type == Lib.Modes.PathEditMode.Type.QUADRATIC_RIGHT) {
- if (Utils.GeometryMath.compare_points (curve_end, point, thresh)) {
- return Lib.Modes.PathEditMode.PointType.CURVE_END;
- }
-
- if (Utils.GeometryMath.compare_points (tangent_2, point, thresh)) {
- return Lib.Modes.PathEditMode.PointType.TANGENT_SECOND;
- }
- } else if (
- type == Lib.Modes.PathEditMode.Type.CUBIC_DOUBLE ||
- type == Lib.Modes.PathEditMode.Type.CUBIC_SINGLE
- ) {
- if (Utils.GeometryMath.compare_points (curve_begin, point, thresh)) {
- return Lib.Modes.PathEditMode.PointType.CURVE_BEGIN;
- }
-
- if (Utils.GeometryMath.compare_points (tangent_1, point, thresh)) {
- return Lib.Modes.PathEditMode.PointType.TANGENT_FIRST;
- }
-
- if (Utils.GeometryMath.compare_points (tangent_2, point, thresh)) {
- return Lib.Modes.PathEditMode.PointType.TANGENT_SECOND;
- }
-
- if (Utils.GeometryMath.compare_points (curve_end, point, thresh)) {
- return Lib.Modes.PathEditMode.PointType.CURVE_END;
- }
- }
-
- return Lib.Modes.PathEditMode.PointType.NONE;
- }
-
- public bool check_tangents_inline () {
- var tangent_mid_x = (tangent_1.x + tangent_2.x) / 2.0;
- var tangent_mid_y = (tangent_1.y + tangent_2.y) / 2.0;
-
- double err_x = (tangent_mid_x - curve_begin.x).abs ();
- double err_y = (tangent_mid_y - curve_begin.y).abs ();
-
- if (err_x <= double.EPSILON && err_y <= double.EPSILON) {
- return true;
- }
-
- return false;
- }
-
- public void translate (double dx, double dy) {
- curve_begin = Geometry.Point (curve_begin.x - dx, curve_begin.y - dy);
- tangent_1 = Geometry.Point (tangent_1.x - dx, tangent_1.y - dy);
- tangent_2 = Geometry.Point (tangent_2.x - dx, tangent_2.y - dy);
- curve_end = Geometry.Point (curve_end.x - dx, curve_end.y - dy);
- }
-
- public void transform (Cairo.Matrix transform, bool invert = false) {
- curve_begin = Utils.GeometryMath.transform_point_around_item_origin (curve_begin, transform, invert);
- tangent_1 = Utils.GeometryMath.transform_point_around_item_origin (tangent_1, transform, invert);
- tangent_2 = Utils.GeometryMath.transform_point_around_item_origin (tangent_2, transform, invert);
- curve_end = Utils.GeometryMath.transform_point_around_item_origin (curve_end, transform, invert);
- }
-
- public void move_tangents (double delta_x, double delta_y, bool is_tan1_reference) {
- if (is_tan1_reference) {
- tangent_1.x -= delta_x;
- tangent_1.y -= delta_y;
-
- tangent_2.x += delta_x;
- tangent_2.y += delta_y;
- } else {
- tangent_1.x += delta_x;
- tangent_1.y += delta_y;
-
- tangent_2.x -= delta_x;
- tangent_2.y -= delta_y;
- }
- }
-
- public void snap_points () {
- curve_begin = Geometry.Point (Math.round (curve_begin.x), Math.round (curve_begin.y));
- tangent_1 = Geometry.Point (Math.round (tangent_1.x), Math.round (tangent_1.y));
- tangent_2 = Geometry.Point (Math.round (tangent_2.x), Math.round (tangent_2.y));
- curve_end = Geometry.Point (Math.round (curve_end.x), Math.round (curve_end.y));
- }
-
-
- public PathSegment.deserialized (Json.Object obj) {
- // TODO:
- }
-
- public Json.Node PathSegment.serialize () {
- var node = new Json.Node (Json.NodeType.OBJECT);
- return node;
- }
-}
-
-public struct Akira.Geometry.SelectedPoint {
- public int sel_index;
- public Lib.Modes.PathEditMode.PointType sel_type;
- public bool tangents_staggered;
-
- public SelectedPoint () {
- tangents_staggered = false;
- }
-}
diff --git a/src/Geometry/Point.vala b/src/Geometry/Point.vala
deleted file mode 100644
index 6d5766b64..000000000
--- a/src/Geometry/Point.vala
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * Copyright (c) 2019-2021 Alecaddd (https://alecaddd.com)
- *
- * This file is part of Akira.
- *
- * Akira 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.
-
- * Akira 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 Akira. If not, see .
- *
- * Authored by: Martin "mbfraga" Fraga
- */
-
- /*
- * Simple 2d point.
- */
-public struct Akira.Geometry.Point {
- public double x;
- public double y;
-
- public Point (double x = 0, double y = 0) {
- this.x = x;
- this.y = y;
- }
-
- public Point.deserialized (Json.Object obj) {
- x = obj.get_double_member ("x");
- y = obj.get_double_member ("y");
- }
-
- public Json.Node serialize () {
- var obj = new Json.Object ();
- obj.set_double_member ("x", x);
- obj.set_double_member ("y", y);
- var node = new Json.Node (Json.NodeType.OBJECT);
- node.set_object (obj);
- return node;
- }
-}
diff --git a/src/Geometry/Quad.vala b/src/Geometry/Quad.vala
deleted file mode 100644
index 18bee6e70..000000000
--- a/src/Geometry/Quad.vala
+++ /dev/null
@@ -1,172 +0,0 @@
-/*
- * Copyright (c) 2019-2021 Alecaddd (https://alecaddd.com)
- *
- * This file is part of Akira.
- *
- * Akira 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.
-
- * Akira 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 Akira. If not, see .
- *
- * Authored by: Martin "mbfraga" Fraga
- */
-
- /*
- * Naive rotated rectangle meant for convenience. This struct does not guarantee
- * that the properties of a rectangle are kept. For all intents and purposes, this
- * is simply a collection of four points and a rotation.
- */
-public struct Akira.Geometry.Quad {
- public Cairo.Matrix transformation;
- public double tl_x;
- public double tl_y;
- public double tr_x;
- public double tr_y;
- public double bl_x;
- public double bl_y;
- public double br_x;
- public double br_y;
-
- public double center_x { get { return (tl_x + tr_x + bl_x + br_x) / 4.0; } }
- public double center_y { get { return (tl_y + tr_y + bl_y + br_y) / 4.0; } }
-
- public double width { get { return Utils.GeometryMath.distance (tl_x, tl_y, tr_x, tr_y).abs (); } }
- public double height { get { return Utils.GeometryMath.distance (tl_x, tl_y, bl_x, bl_y).abs (); } }
-
- public void top_bottom (ref double top, ref double bottom) {
- Utils.GeometryMath.min_max_coords (tl_y, tr_y, bl_y, br_y, ref top, ref bottom);
- }
-
- public void left_right (ref double left, ref double right) {
- Utils.GeometryMath.min_max_coords (tl_x, tr_x, bl_x, br_x, ref left, ref right);
- }
-
- public Rectangle bounding_box {
- get {
- double min_x = 0;
- double max_x = 0;
- Utils.GeometryMath.min_max_coords (tl_x, tr_x, bl_x, br_x, ref min_x, ref max_x);
-
- double min_y = 0;
- double max_y = 0;
- Utils.GeometryMath.min_max_coords (tl_y, tr_y, bl_y, br_y, ref min_y, ref max_y);
-
- return Rectangle .with_coordinates (min_x, min_y, max_x, max_y);
- }
- }
-
-
- public Quad () {
- transformation = Cairo.Matrix.identity ();
- tl_x = 0;
- tl_y = 0;
- tr_x = 0;
- tr_y = 0;
- bl_x = 0;
- bl_y = 0;
- br_x = 0;
- br_y = 0;
- }
-
- public Quad.from_rectangle (Geometry.Rectangle rect) {
- transformation = Cairo.Matrix.identity ();
- tl_x = rect.left;
- tl_y = rect.top;
- tr_x = rect.right;
- tr_y = rect.top;
- bl_x = rect.left;
- bl_y = rect.bottom;
- br_x = rect.right;
- br_y = rect.bottom;
- }
-
- public Quad.from_components (
- double center_x,
- double center_y,
- double width,
- double height,
- Cairo.Matrix transform
- ) {
- transformation = transform;
-
- var hw = width / 2.0;
- var hh = height / 2.0;
-
- tl_x = - hw;
- tl_y = - hh;
- br_x = hw;
- br_y = hh;
-
- var woffx = width;
- var woffy = 0.0;
- transform.transform_distance (ref tl_x, ref tl_y);
- transform.transform_distance (ref br_x, ref br_y);
- transform.transform_distance (ref woffx, ref woffy);
-
- tl_x = center_x + tl_x;
- tl_y = center_y + tl_y;
-
- tr_x = tl_x + woffx;
- tr_y = tl_y + woffy;
-
- br_x = center_x + br_x;
- br_y = center_y + br_y;
- bl_x = br_x - woffx;
- bl_y = br_y - woffy;
-
- transform.x0 = center_x - hw;
- transform.y0 = center_y - hh;
- }
-
- public bool contains (double x, double y) {
- if (!bounding_box.contains (x, y)) {
- return false;
- }
-
- return Utils.GeometryMath.points_on_same_side_of_line (tl_x, tl_y, tr_x, tr_y, br_x, br_y, x, y)
- && Utils.GeometryMath.points_on_same_side_of_line (tr_x, tr_y, br_x, br_y, bl_x, bl_y, x, y)
- && Utils.GeometryMath.points_on_same_side_of_line (br_x, br_y, bl_x, bl_y, tl_x, tl_y, x, y)
- && Utils.GeometryMath.points_on_same_side_of_line (bl_x, bl_y, tl_x, tl_y, tr_x, tr_y, x, y);
- }
-
- public void translate (double dx, double dy) {
- tl_x += dx;
- tr_x += dx;
- bl_x += dx;
- br_x += dx;
-
- tl_y += dy;
- tr_y += dy;
- bl_y += dy;
- br_y += dy;
- }
-
- public void transform (Cairo.Matrix matrix) {
- transformation = matrix;
- matrix.transform_point (ref tl_x, ref tl_y);
- matrix.transform_point (ref tr_x, ref tr_y);
- matrix.transform_point (ref bl_x, ref bl_y);
- matrix.transform_point (ref br_x, ref br_y);
- }
-
- public string to_string () {
- return "tl: %f %f tr: %f %f br: %f %f bl: %f %f".printf (
- tl_x,
- tl_y,
- tr_x,
- tr_y,
- br_x,
- br_y,
- bl_x,
- bl_y
- );
- }
-}
diff --git a/src/Geometry/Rectangle.vala b/src/Geometry/Rectangle.vala
deleted file mode 100644
index 8452163e0..000000000
--- a/src/Geometry/Rectangle.vala
+++ /dev/null
@@ -1,84 +0,0 @@
-/*
- * Copyright (c) 2019-2021 Alecaddd (https://alecaddd.com)
- *
- * This file is part of Akira.
- *
- * Akira 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.
-
- * Akira 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 Akira. If not, see .
- *
- * Authored by: Martin "mbfraga" Fraga
- */
-
- /*
- * Naive rectangle. It does not guarantee relative positions of left/right, top/left
- * unless the `with_coordinates` constructor is used.
- */
-public struct Akira.Geometry.Rectangle {
- public double top;
- public double left;
- public double bottom;
- public double right;
-
- public double center_x { get { return (left + right) / 2.0; } }
- public double center_y { get { return (bottom + top) / 2.0; } }
- public double width { get { return (right - left).abs (); } }
- public double height { get { return (bottom - top).abs (); } }
-
- public Rectangle.empty () {
- top = 0;
- bottom = 0;
- left = 0;
- right = 0;
- }
-
- public Rectangle.with_coordinates (double x0, double y0, double x1, double y1) {
- if (x0 < x1) {
- left = x0;
- right = x1;
- } else {
- right = x0;
- left = x1;
- }
-
- if (y0 < y1) {
- top = y0;
- bottom = y1;
- } else {
- bottom = y0;
- top = y1;
- }
- }
-
- public bool contains (double x, double y) {
- return (left < x < right) && (top < y < bottom);
- }
-
- public bool contains_bound (Geometry.Rectangle bound) {
- return (left <= bound.left) && (top <= bound.top) && (right >= bound.right) && (bottom >= bound.bottom);
- }
-
- public bool does_not_contain (double x, double y) {
- return x < left || x > right || y < top || y > bottom;
- }
-
- public void translate (double dx, double dy) {
- left += dx;
- right += dx;
- top += dy;
- bottom += dy;
- }
-
- public string to_string () {
- return "t: %f l: %f b: %f r: %f".printf (top, left, bottom , right);
- }
-}
diff --git a/src/Geometry/TransformedRectangle.vala b/src/Geometry/TransformedRectangle.vala
deleted file mode 100644
index 444884ccf..000000000
--- a/src/Geometry/TransformedRectangle.vala
+++ /dev/null
@@ -1,73 +0,0 @@
-/*
- * Copyright (c) 2019-2021 Alecaddd (https://alecaddd.com)
- *
- * This file is part of Akira.
- *
- * Akira 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.
-
- * Akira 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 Akira. If not, see .
- *
- * Authored by: Martin "mbfraga" Fraga
- */
-
- /*
- * Consists of an original rectangle, and a matrix to transform it to the
- * world coordinates.
- */
- public struct Akira.Geometry.TransformedRectangle {
- public Rectangle rect;
- public Cairo.Matrix matrix;
-
- public TransformedRectangle () {}
-
- public TransformedRectangle.with_geometry (Rectangle rectangle, Cairo.Matrix matrix) {
- rect = rectangle;
- this.matrix = matrix;
- }
-
- public TransformedRectangle.empty () {
- rect = Rectangle.empty ();
- this.matrix = Cairo.Matrix.identity ();
- }
-
- public Quad quad () {
- var quad = Quad.from_rectangle (rect);
- quad.transform (matrix);
- return quad;
- }
-
- /*
- * Maps x, y from the world coordinates to the rect
- * coordinates.
- */
- public void map_to_local (ref double x, ref double y) {
- var inv = matrix;
- inv.invert ();
- inv.transform_point (ref x, ref y);
- }
-
- /*
- * Map x, y from the rect coordinates to the world coordinates.
- */
- public void map_from_local (ref double x, ref double y) {
- matrix.transform_point (ref x, ref y);
- }
-
- /*
- * Returns true if the transformed rectangle contains the x, y position
- * in the world coordinates defined by the `matrix` mapping
- */
- public bool contains (double x, double y) {
- map_to_local (ref x, ref y);
- return rect.contains (x, y);
- }
-}
diff --git a/src/Layouts/Alignment/AlignmentPanel.vala b/src/Layouts/Alignment/AlignmentPanel.vala
deleted file mode 100644
index 781fa746d..000000000
--- a/src/Layouts/Alignment/AlignmentPanel.vala
+++ /dev/null
@@ -1,113 +0,0 @@
-/*
- * Copyright (c) 2019-2022 Alecaddd (https://alecaddd.com)
- *
- * This file is part of Akira.
- *
- * Akira 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.
-
- * Akira 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 Akira. If not, see .
- *
- * Authored by: Giacomo "giacomoalbe" Alberini
- * Alessandro "Alecaddd" Castellani
- */
-public class Akira.Layouts.Alignment.AlignmentPanel : Gtk.Grid {
- public unowned Lib.ViewCanvas view_canvas { get; construct; }
-
- private Gee.ArrayList buttons;
- private int grid_column { get; set; default = 0; }
-
- private struct AlignBoxItem {
- public string type;
- public Utils.ItemAlignment.AlignmentDirection? alignment_direction;
- public string? icon_name;
- public string? tooltip_text;
- public string[]? accels;
-
- public AlignBoxItem (
- string type,
- Utils.ItemAlignment.AlignmentDirection? alignment_direction = null,
- string? icon_name = null,
- string? tooltip_text = null,
- string[]? accels = null) {
- this.type = type;
- this.alignment_direction = alignment_direction;
- this.icon_name = icon_name;
- this.tooltip_text = tooltip_text;
- this.accels = accels;
- }
- }
-
- private AlignBoxItem[] align_items_buttons = {
- //AlignBoxItem ("btn", Utils.ItemAlignment.AlignmentDirection.HEVEN, "distribute-horizontal-center", _("Distribute Horizontally"), {"1"}),
- //AlignBoxItem ("btn", Utils.ItemAlignment.AlignemtDirection.VEVEN, "distribute-vertical-center", _("Distribute Vertically"), {"2"}),
- //AlignBoxItem ("sep"),
- AlignBoxItem ("btn", Utils.ItemAlignment.AlignmentDirection.LEFT, "align-horizontal-left", _("Align Left"), {"1"}),
- AlignBoxItem ("btn", Utils.ItemAlignment.AlignmentDirection.HCENTER, "align-horizontal-center", _("Align Center"), {"2"}),
- AlignBoxItem ("btn", Utils.ItemAlignment.AlignmentDirection.RIGHT, "align-horizontal-right", _("Align Right"), {"3"}),
- AlignBoxItem ("sep"),
- AlignBoxItem ("btn", Utils.ItemAlignment.AlignmentDirection.TOP, "align-vertical-top", _("Align Top"), {"4"}),
- AlignBoxItem ("btn", Utils.ItemAlignment.AlignmentDirection.VCENTER, "align-vertical-center", _("Align Middle"), {"5"}),
- AlignBoxItem ("btn", Utils.ItemAlignment.AlignmentDirection.BOTTOM, "align-vertical-bottom", _("Align Bottom"), {"6"})
- };
-
- public AlignmentPanel (Lib.ViewCanvas view_canvas) {
- Object (view_canvas: view_canvas);
- }
-
- construct {
- get_style_context ().add_class ("alignment-panel");
- column_homogeneous = true;
- hexpand = true;
- buttons = new Gee.ArrayList ();
-
- foreach (var item in align_items_buttons) {
- switch (item.type) {
- case "sep":
- var separator = new Gtk.Separator (Gtk.Orientation.VERTICAL) {
- halign = Gtk.Align.CENTER,
- margin_top = margin_bottom = 4
- };
-
- attach (separator, grid_column++, 0, 1, 1);
- break;
-
- case "btn":
- var button = new Gtk.Button () {
- halign = valign = Gtk.Align.CENTER,
- can_focus = false,
- sensitive = false,
- tooltip_markup = Granite.markup_accel_tooltip (item.accels, item.tooltip_text)
- };
- button.add (new Widgets.ButtonImage (item.icon_name, Gtk.IconSize.SMALL_TOOLBAR));
- button.clicked.connect (() => {
- view_canvas.window.event_bus.selection_align (item.alignment_direction);
- });
- button.get_style_context ().add_class (Gtk.STYLE_CLASS_FLAT);
- button.get_style_context ().add_class ("button-rounded");
-
- attach (button, grid_column++, 0, 1, 1);
- buttons.add (button);
- break;
- }
- }
-
- view_canvas.window.event_bus.selection_modified.connect (on_selection_modified);
- }
-
- private void on_selection_modified () {
- unowned var sm = view_canvas.selection_manager;
- bool is_sensitive = sm.count () > 1;
- foreach (var button in buttons) {
- button.sensitive = is_sensitive;
- }
- }
-}
diff --git a/src/Layouts/BordersList/BorderItemModel.vala b/src/Layouts/BordersList/BorderItemModel.vala
deleted file mode 100644
index 5a45d3cd4..000000000
--- a/src/Layouts/BordersList/BorderItemModel.vala
+++ /dev/null
@@ -1,80 +0,0 @@
-/*
- * Copyright (c) 2022 Alecaddd (https://alecaddd.com)
- *
- * This file is part of Akira.
- *
- * Akira 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.
-
- * Akira 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 Akira. If not, see .
- *
- * Authored by: Alessandro "Alecaddd" Castellani
- */
-
-/*
- * Simple Object to be handled by the BordersListBoxModel and to give easy access
- * the border component of the Lib.Items.ModelNode.
- */
-public class Akira.Layouts.BordersList.BorderItemModel : Models.ColorModel {
- private unowned Lib.ViewCanvas _view_canvas;
-
- private Lib.Items.ModelInstance _cached_instance;
-
- public int border_id;
-
- public override void on_value_changed () {
- if (block_signal > 0) {
- return;
- }
-
- unowned var im = _view_canvas.items_manager;
- var node = im.item_model.node_from_id (_cached_instance.id);
- assert (node != null);
-
- var new_color = Lib.Components.Color.from_rgba (color, hidden);
- var new_borders = node.instance.components.borders.copy ();
- new_borders.replace (Lib.Components.Borders.Border (border_id, new_color));
- node.instance.components.borders = new_borders;
-
- im.item_model.alert_node_changed (node, Lib.Components.Component.Type.COMPILED_BORDER);
- im.compile_model ();
- }
-
- public override void delete () {
- unowned var im = _view_canvas.items_manager;
- var node = im.item_model.node_from_id (_cached_instance.id);
- assert (node != null);
-
- var new_borders = node.instance.components.borders.copy ();
- new_borders.remove (border_id);
- node.instance.components.borders = new_borders;
-
- im.item_model.alert_node_changed (node, Lib.Components.Component.Type.COMPILED_BORDER);
- im.compile_model ();
- }
-
- public BorderItemModel (Lib.ViewCanvas view_canvas, Lib.Items.ModelNode node, int border_id) {
- update_node (node, border_id);
- _view_canvas = view_canvas;
- }
-
- private void update_node (Lib.Items.ModelNode new_node, int border_id) {
- _cached_instance = new_node.instance;
- this.border_id = border_id;
-
- var blocker = new SignalBlocker (this);
- (blocker);
-
- var border = _cached_instance.components.borders.border_from_id (border_id);
- color = border.color;
- hidden = border.hidden;
- }
-}
diff --git a/src/Layouts/BordersList/BorderListBox.vala b/src/Layouts/BordersList/BorderListBox.vala
deleted file mode 100644
index bea90d6bf..000000000
--- a/src/Layouts/BordersList/BorderListBox.vala
+++ /dev/null
@@ -1,96 +0,0 @@
-/*
- * Copyright (c) 2022 Alecaddd (https://alecaddd.com)
- *
- * This file is part of Akira.
- *
- * Akira 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.
-
- * Akira 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 Akira. If not, see .
- *
- * Authored by: Alessandro "Alecaddd" Castellani
- */
-
-/*
- * The borders panel.
- */
-public class Akira.Layouts.BordersList.BorderListBox : VirtualizingSimpleListBox {
- public unowned Lib.ViewCanvas view_canvas { get; construct; }
-
- private Gee.HashMap borders;
- private BorderListStore list_store;
-
- public BorderListBox (Lib.ViewCanvas canvas) {
- Object (
- view_canvas: canvas
- );
-
- borders = new Gee.HashMap ();
- list_store = new BorderListStore ();
- // list_store.set_sort_func (borders_sort_function);
-
- model = list_store;
-
- // Factory function to reuse the already generated row UI element when
- // a new border is created or the borders list scrolls to reveal borders
- // outside of the viewport.
- factory_func = (item, old_widget) => {
- BorderListItem? row = null;
- if (old_widget != null) {
- row = old_widget as BorderListItem;
- } else {
- row = new BorderListItem (view_canvas);
- }
-
- row.assign ((BorderItemModel) item);
- row.show_all ();
-
- return row;
- };
- }
-
- public void refresh_list () {
- if (borders.size > 0) {
- var removed = borders.size;
- borders.clear ();
- list_store.remove_all ();
- list_store.items_changed (0, removed, 0);
- }
-
- unowned var sm = view_canvas.selection_manager;
- var count = sm.count ();
- if (count == 0) {
- return;
- }
-
- var added = 0;
- foreach (var selected in sm.selection.nodes.values) {
- // Break out of the look if we have multiple selected items and more
- // than 4 fills to avoid creating too many widgets at once.
- if (added > 4 && count > 1) {
- break;
- }
-
- var node = selected.node;
- if (node.instance.components.borders == null) {
- continue;
- }
- foreach (var border in node.instance.components.borders.data) {
- var item = new BorderItemModel (view_canvas, node, border.id);
- borders[node.id] = item;
- list_store.add (item);
- added++;
- }
- }
-
- list_store.items_changed (0, 0, added);
- }
-}
diff --git a/src/Layouts/BordersList/BorderListItem.vala b/src/Layouts/BordersList/BorderListItem.vala
deleted file mode 100644
index d90a1d32d..000000000
--- a/src/Layouts/BordersList/BorderListItem.vala
+++ /dev/null
@@ -1,122 +0,0 @@
-/*
- * Copyright (c) 2022 Alecaddd (https://alecaddd.com)
- *
- * This file is part of Akira.
- *
- * Akira 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.
-
- * Akira 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 Akira. If not, see .
- *
- * Authored by: Alessandro "Alecaddd" Castellani
- */
-
-/*
- * The single color border row.
- */
-public class Akira.Layouts.BordersList.BorderListItem : VirtualizingListBoxRow {
- public unowned Lib.ViewCanvas view_canvas { get; construct; }
-
- private BorderItemModel model;
-
- private Widgets.ColorButton color_button;
- private Widgets.ColorField color_field;
- private Widgets.OpacityField opacity_field;
- private Widgets.EyeDropperButton eyedropper_button;
- private Widgets.HideButton hide_button;
- private Gtk.Button delete_button;
-
- private bool? current_state = null;
-
- public BorderListItem (Lib.ViewCanvas canvas) {
- Object (
- view_canvas: canvas
- );
-
- get_style_context ().add_class ("item-property");
-
- var grid = new Gtk.Grid () {
- margin = 3
- };
-
- var container = new Gtk.Grid ();
- var context = container.get_style_context ();
- context.add_class ("selected-color-container");
- context.add_class ("bg-pattern");
-
- color_button = new Widgets.ColorButton ();
- container.add (color_button);
-
- eyedropper_button = new Widgets.EyeDropperButton () {};
- grid.add (container);
- grid.add (eyedropper_button);
-
- color_field = new Widgets.ColorField (view_canvas);
- grid.add (color_field);
-
- opacity_field = new Widgets.OpacityField (view_canvas);
- grid.add (opacity_field);
-
- hide_button = new Widgets.HideButton () {};
- grid.add (hide_button);
-
- delete_button = new Gtk.Button.from_icon_name ("user-trash-symbolic", Gtk.IconSize.SMALL_TOOLBAR) {
- valign = Gtk.Align.CENTER,
- can_focus = false,
- tooltip_text = _("Remove color"),
- margin_start = 3
- };
- delete_button.get_style_context ().add_class (Gtk.STYLE_CLASS_FLAT);
- delete_button.get_style_context ().add_class ("button-rounded");
- delete_button.clicked.connect (delete_border);
- grid.add (delete_button);
-
- add (grid);
- }
-
- ~BorderListItem () {
- model.value_changed.disconnect (on_model_changed);
- }
-
- public void assign (BorderItemModel data) {
- model_item = data;
- model = (BorderItemModel) model_item;
- color_button.assign (model);
- color_field.assign (model);
- opacity_field.assign (model);
- hide_button.assign (model);
- eyedropper_button.assign (model);
-
- model.value_changed.connect (on_model_changed);
- on_model_changed ();
- }
-
- private void on_model_changed () {
- if (current_state == model.hidden) {
- return;
- }
-
- if (model.hidden) {
- get_style_context ().add_class ("disabled");
- selectable = false;
- } else {
- get_style_context ().remove_class ("disabled");
- selectable = true;
- }
-
- current_state = model.hidden;
- }
-
- private void delete_border () {
- model.delete ();
- view_canvas.window.main_window.refresh_borders ();
- }
-}
diff --git a/src/Layouts/BordersList/BorderListStore.vala b/src/Layouts/BordersList/BorderListStore.vala
deleted file mode 100644
index a802cad72..000000000
--- a/src/Layouts/BordersList/BorderListStore.vala
+++ /dev/null
@@ -1,115 +0,0 @@
-/*
- * Copyright (c) 2022 Alecaddd (https://alecaddd.com)
- *
- * This file is part of Akira.
- *
- * Akira 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.
-
- * Akira 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 Akira. If not, see .
- *
- * Authored by: Alessandro "Alecaddd" Castellani
- */
-
-/*
- * The model holding the borders panel rows.
- */
-public class Akira.Layouts.BordersList.BorderListStore : VirtualizingListBoxModel {
- public delegate bool RowVisibilityFunc (GLib.Object row);
-
- private GLib.Sequence data = new GLib.Sequence ();
- private uint last_position = uint.MAX;
- private GLib.SequenceIter? last_iter;
- private unowned GLib.CompareDataFunc compare_func;
- private unowned RowVisibilityFunc filter_func;
-
- public override uint get_n_items () {
- return data.get_length ();
- }
-
- public override GLib.Object? get_item (uint index) {
- return get_item_internal (index);
- }
-
- public override GLib.Object? get_item_unfiltered (uint index) {
- return get_item_internal (index, true);
- }
-
- private GLib.Object? get_item_internal (uint index, bool unfiltered = false) {
- GLib.SequenceIter? iter = null;
-
- if (last_position != uint.MAX) {
- if (last_position == index + 1) {
- iter = last_iter.prev ();
- } else if (last_position == index - 1) {
- iter = last_iter.next ();
- } else if (last_position == index) {
- iter = last_iter;
- }
- }
-
- if (iter == null) {
- iter = data.get_iter_at_pos ((int)index);
- }
-
- last_iter = iter;
- last_position = index;
-
- if (iter.is_end ()) {
- return null;
- }
-
- if (filter_func == null) {
- return iter.get ();
- } else if (filter_func (iter.get ())) {
- return iter.get ();
- } else if (unfiltered) {
- return iter.get ();
- } else {
- return null;
- }
- }
-
- public void add (BorderItemModel model) {
- if (compare_func != null) {
- this.data.insert_sorted (model, compare_func);
- } else {
- this.data.prepend (model);
- }
-
- last_iter = null;
- last_position = uint.MAX;
- }
-
- public void remove (BorderItemModel data) {
- var iter = this.data.get_iter_at_pos (get_index_of_unfiltered (data));
- iter.remove ();
-
- last_iter = null;
- last_position = uint.MAX;
- }
-
- public void remove_all () {
- data.get_begin_iter ().remove_range (data.get_end_iter ());
- unselect_all ();
-
- last_iter = null;
- last_position = uint.MAX;
- }
-
- public void set_sort_func (GLib.CompareDataFunc function) {
- this.compare_func = function;
- }
-
- public void set_filter_func (RowVisibilityFunc? function) {
- filter_func = function;
- }
-}
diff --git a/src/Layouts/BordersList/BordersPanel.vala b/src/Layouts/BordersList/BordersPanel.vala
deleted file mode 100644
index 750dd917d..000000000
--- a/src/Layouts/BordersList/BordersPanel.vala
+++ /dev/null
@@ -1,123 +0,0 @@
-/**
- * Copyright (c) 2022 Alecaddd (https://alecaddd.com)
- *
- * This file is part of Akira.
- *
- * Akira 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.
-
- * Akira 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 Akira. If not, see .
- *
- * Authored by: Alessandro "alecaddd" Castellani
- */
-
-public class Akira.Layouts.BordersList.BordersPanel : Gtk.Grid {
- public unowned Lib.ViewCanvas view_canvas { get; construct; }
-
- public BorderListBox borders_listbox;
-
- public BordersPanel (Lib.ViewCanvas canvas) {
- Object (
- view_canvas: canvas
- );
-
- var title_cont = new Gtk.Grid () {
- orientation = Gtk.Orientation.HORIZONTAL,
- hexpand = true
- };
- title_cont.get_style_context ().add_class ("option-panel");
-
- var label = new Gtk.Label (_("Borders")) {
- halign = Gtk.Align.FILL,
- xalign = 0,
- hexpand = true,
- ellipsize = Pango.EllipsizeMode.END
- };
-
- var add_btn = new Gtk.Button.from_icon_name ("list-add-symbolic", Gtk.IconSize.SMALL_TOOLBAR) {
- can_focus = false,
- valign = Gtk.Align.CENTER,
- halign = Gtk.Align.CENTER,
- tooltip_text = _("Add border color")
- };
- add_btn.clicked.connect (add_border);
- add_btn.get_style_context ().add_class (Gtk.STYLE_CLASS_FLAT);
-
- title_cont.attach (label, 0, 0, 1, 1);
- title_cont.attach (add_btn, 1, 0, 1, 1);
-
- attach (title_cont, 0, 0, 1, 1);
-
- borders_listbox = new BorderListBox (view_canvas);
- attach (borders_listbox, 0, 1, 1, 1);
-
- // Show the widget by default.
- show_all ();
- // But then hide it right after so we can toggle it.
- visible = false;
- no_show_all = true;
-
- view_canvas.window.event_bus.selection_modified.connect (on_selection_modified);
- }
-
- private void on_selection_modified () {
- unowned var sm = view_canvas.selection_manager;
-
- bool is_visible = false;
- foreach (var selected in sm.selection.nodes.values) {
- // Show the borders panel only if at least one item is not an artboard.
- if (!selected.node.instance.is_artboard) {
- is_visible = true;
- break;
- }
- }
-
- visible = is_visible;
- no_show_all = !is_visible;
-
- if (is_visible) {
- borders_listbox.refresh_list ();
- }
- }
-
- private void add_border () {
- unowned var sm = view_canvas.selection_manager;
- if (sm.count () == 0) {
- return;
- }
-
- var border_rgba = Gdk.RGBA ();
- border_rgba.parse (settings.border_color);
- var color = Lib.Components.Color.from_rgba (border_rgba);
-
- unowned var im = _view_canvas.items_manager;
- foreach (var selected in sm.selection.nodes.values) {
- // Don't add borders for Artboards.
- if (selected.node.instance.is_artboard) {
- continue;
- }
-
- unowned var old_borders = selected.node.instance.components.borders;
- Lib.Components.Borders? new_borders = (old_borders == null) ? null : old_borders.copy ();
- double? size = null;
- if (new_borders == null) {
- new_borders = new Lib.Components.Borders ();
- size = settings.border_size;
- }
-
- new_borders.append_border_with_color (color, size);
- selected.node.instance.components.borders = new_borders;
- im.item_model.alert_node_changed (selected.node, Lib.Components.Component.Type.COMPILED_BORDER);
- }
- im.compile_model ();
- borders_listbox.refresh_list ();
- }
-}
diff --git a/src/Layouts/FillsList/FillItemModel.vala b/src/Layouts/FillsList/FillItemModel.vala
deleted file mode 100644
index c924206fd..000000000
--- a/src/Layouts/FillsList/FillItemModel.vala
+++ /dev/null
@@ -1,80 +0,0 @@
-/*
- * Copyright (c) 2022 Alecaddd (https://alecaddd.com)
- *
- * This file is part of Akira.
- *
- * Akira 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.
-
- * Akira 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 Akira. If not, see .
- *
- * Authored by: Alessandro "Alecaddd" Castellani
- */
-
-/*
- * Simple Object to be handled by the FillsListBoxModel and to give easy access
- * the fill component of the Lib.Items.ModelNode.
- */
-public class Akira.Layouts.FillsList.FillItemModel : Models.ColorModel {
- private unowned Akira.Lib.ViewCanvas _view_canvas;
-
- private Lib.Items.ModelInstance _cached_instance;
-
- public int fill_id;
-
- public override void on_value_changed () {
- if (block_signal > 0) {
- return;
- }
-
- unowned var im = _view_canvas.items_manager;
- var node = im.item_model.node_from_id (_cached_instance.id);
- assert (node != null);
-
- var new_color = Lib.Components.Color.from_rgba (color, hidden);
- var new_fills = node.instance.components.fills.copy ();
- new_fills.replace (Lib.Components.Fills.Fill (fill_id, new_color));
- node.instance.components.fills = new_fills;
-
- im.item_model.alert_node_changed (node, Lib.Components.Component.Type.COMPILED_FILL);
- im.compile_model ();
- }
-
- public override void delete () {
- unowned var im = _view_canvas.items_manager;
- var node = im.item_model.node_from_id (_cached_instance.id);
- assert (node != null);
-
- var new_fills = node.instance.components.fills.copy ();
- new_fills.remove (fill_id);
- node.instance.components.fills = new_fills;
-
- im.item_model.alert_node_changed (node, Lib.Components.Component.Type.COMPILED_FILL);
- im.compile_model ();
- }
-
- public FillItemModel (Lib.ViewCanvas view_canvas, Lib.Items.ModelNode node, int fill_id) {
- update_node (node, fill_id);
- _view_canvas = view_canvas;
- }
-
- private void update_node (Lib.Items.ModelNode new_node, int fill_id) {
- _cached_instance = new_node.instance;
- this.fill_id = fill_id;
-
- var blocker = new SignalBlocker (this);
- (blocker);
-
- var fill = _cached_instance.components.fills.fill_from_id (fill_id);
- color = fill.color;
- hidden = fill.hidden;
- }
-}
diff --git a/src/Layouts/FillsList/FillListBox.vala b/src/Layouts/FillsList/FillListBox.vala
deleted file mode 100644
index e618bcc57..000000000
--- a/src/Layouts/FillsList/FillListBox.vala
+++ /dev/null
@@ -1,96 +0,0 @@
-/*
- * Copyright (c) 2022 Alecaddd (https://alecaddd.com)
- *
- * This file is part of Akira.
- *
- * Akira 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.
-
- * Akira 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 Akira. If not, see .
- *
- * Authored by: Alessandro "Alecaddd" Castellani
- */
-
-/*
- * The fills panel.
- */
-public class Akira.Layouts.FillsList.FillListBox : VirtualizingSimpleListBox {
- public unowned Akira.Lib.ViewCanvas view_canvas { get; construct; }
-
- private Gee.HashMap fills;
- private FillListStore list_store;
-
- public FillListBox (Akira.Lib.ViewCanvas canvas) {
- Object (
- view_canvas: canvas
- );
-
- fills = new Gee.HashMap ();
- list_store = new FillListStore ();
- // list_store.set_sort_func (fills_sort_function);
-
- model = list_store;
-
- // Factory function to reuse the already generated row UI element when
- // a new fill is created or the fills list scrolls to reveal fills
- // outside of the viewport.
- factory_func = (item, old_widget) => {
- FillListItem? row = null;
- if (old_widget != null) {
- row = old_widget as FillListItem;
- } else {
- row = new FillListItem (view_canvas);
- }
-
- row.assign ((FillItemModel) item);
- row.show_all ();
-
- return row;
- };
- }
-
- public void refresh_list () {
- if (fills.size > 0) {
- var removed = fills.size;
- fills.clear ();
- list_store.remove_all ();
- list_store.items_changed (0, removed, 0);
- }
-
- unowned var sm = view_canvas.selection_manager;
- var count = sm.count ();
- if (count == 0) {
- return;
- }
-
- var added = 0;
- foreach (var selected in sm.selection.nodes.values) {
- // Break out of the look if we have multiple selected items and more
- // than 4 fills to avoid creating too many widgets at once.
- if (added > 4 && count > 1) {
- break;
- }
-
- var node = selected.node;
- if (node.instance.components.fills == null) {
- continue;
- }
- foreach (var fill in node.instance.components.fills.data) {
- var item = new FillItemModel (view_canvas, node, fill.id);
- fills[node.id] = item;
- list_store.add (item);
- added++;
- }
- }
-
- list_store.items_changed (0, 0, added);
- }
-}
diff --git a/src/Layouts/FillsList/FillListItem.vala b/src/Layouts/FillsList/FillListItem.vala
deleted file mode 100644
index 8421465c4..000000000
--- a/src/Layouts/FillsList/FillListItem.vala
+++ /dev/null
@@ -1,122 +0,0 @@
-/*
- * Copyright (c) 2022 Alecaddd (https://alecaddd.com)
- *
- * This file is part of Akira.
- *
- * Akira 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.
-
- * Akira 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 Akira. If not, see .
- *
- * Authored by: Alessandro "Alecaddd" Castellani
- */
-
-/*
- * The single color fill row.
- */
-public class Akira.Layouts.FillsList.FillListItem : VirtualizingListBoxRow {
- public unowned Lib.ViewCanvas view_canvas { get; construct; }
-
- private FillItemModel model;
-
- private Widgets.ColorButton color_button;
- private Widgets.ColorField color_field;
- private Widgets.OpacityField opacity_field;
- private Widgets.EyeDropperButton eyedropper_button;
- private Widgets.HideButton hide_button;
- private Gtk.Button delete_button;
-
- private bool? current_state = null;
-
- public FillListItem (Akira.Lib.ViewCanvas canvas) {
- Object (
- view_canvas: canvas
- );
-
- get_style_context ().add_class ("item-property");
-
- var grid = new Gtk.Grid () {
- margin = 3
- };
-
- var container = new Gtk.Grid ();
- var context = container.get_style_context ();
- context.add_class ("selected-color-container");
- context.add_class ("bg-pattern");
-
- color_button = new Widgets.ColorButton ();
- container.add (color_button);
-
- eyedropper_button = new Widgets.EyeDropperButton () {};
- grid.add (container);
- grid.add (eyedropper_button);
-
- color_field = new Widgets.ColorField (view_canvas);
- grid.add (color_field);
-
- opacity_field = new Widgets.OpacityField (view_canvas);
- grid.add (opacity_field);
-
- hide_button = new Widgets.HideButton () {};
- grid.add (hide_button);
-
- delete_button = new Gtk.Button.from_icon_name ("user-trash-symbolic", Gtk.IconSize.SMALL_TOOLBAR) {
- valign = Gtk.Align.CENTER,
- can_focus = false,
- tooltip_text = _("Remove color"),
- margin_start = 3
- };
- delete_button.get_style_context ().add_class (Gtk.STYLE_CLASS_FLAT);
- delete_button.get_style_context ().add_class ("button-rounded");
- delete_button.clicked.connect (delete_fill);
- grid.add (delete_button);
-
- add (grid);
- }
-
- ~FillListItem () {
- model.value_changed.disconnect (on_model_changed);
- }
-
- public void assign (FillItemModel data) {
- model_item = data;
- model = (FillItemModel) model_item;
- color_button.assign (model);
- color_field.assign (model);
- opacity_field.assign (model);
- hide_button.assign (model);
- eyedropper_button.assign (model);
-
- model.value_changed.connect (on_model_changed);
- on_model_changed ();
- }
-
- private void on_model_changed () {
- if (current_state == model.hidden) {
- return;
- }
-
- if (model.hidden) {
- get_style_context ().add_class ("disabled");
- selectable = false;
- } else {
- get_style_context ().remove_class ("disabled");
- selectable = true;
- }
-
- current_state = model.hidden;
- }
-
- private void delete_fill () {
- model.delete ();
- view_canvas.window.main_window.refresh_fills ();
- }
-}
diff --git a/src/Layouts/FillsList/FillListStore.vala b/src/Layouts/FillsList/FillListStore.vala
deleted file mode 100644
index 0adddba3b..000000000
--- a/src/Layouts/FillsList/FillListStore.vala
+++ /dev/null
@@ -1,115 +0,0 @@
-/*
- * Copyright (c) 2022 Alecaddd (https://alecaddd.com)
- *
- * This file is part of Akira.
- *
- * Akira 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.
-
- * Akira 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 Akira. If not, see .
- *
- * Authored by: Alessandro "Alecaddd" Castellani
- */
-
-/*
- * The model holding the fills panel rows.
- */
-public class Akira.Layouts.FillsList.FillListStore : VirtualizingListBoxModel {
- public delegate bool RowVisibilityFunc (GLib.Object row);
-
- private GLib.Sequence data = new GLib.Sequence ();
- private uint last_position = uint.MAX;
- private GLib.SequenceIter? last_iter;
- private unowned GLib.CompareDataFunc compare_func;
- private unowned RowVisibilityFunc filter_func;
-
- public override uint get_n_items () {
- return data.get_length ();
- }
-
- public override GLib.Object? get_item (uint index) {
- return get_item_internal (index);
- }
-
- public override GLib.Object? get_item_unfiltered (uint index) {
- return get_item_internal (index, true);
- }
-
- private GLib.Object? get_item_internal (uint index, bool unfiltered = false) {
- GLib.SequenceIter? iter = null;
-
- if (last_position != uint.MAX) {
- if (last_position == index + 1) {
- iter = last_iter.prev ();
- } else if (last_position == index - 1) {
- iter = last_iter.next ();
- } else if (last_position == index) {
- iter = last_iter;
- }
- }
-
- if (iter == null) {
- iter = data.get_iter_at_pos ((int)index);
- }
-
- last_iter = iter;
- last_position = index;
-
- if (iter.is_end ()) {
- return null;
- }
-
- if (filter_func == null) {
- return iter.get ();
- } else if (filter_func (iter.get ())) {
- return iter.get ();
- } else if (unfiltered) {
- return iter.get ();
- } else {
- return null;
- }
- }
-
- public void add (FillItemModel model) {
- if (compare_func != null) {
- this.data.insert_sorted (model, compare_func);
- } else {
- this.data.prepend (model);
- }
-
- last_iter = null;
- last_position = uint.MAX;
- }
-
- public void remove (FillItemModel data) {
- var iter = this.data.get_iter_at_pos (get_index_of_unfiltered (data));
- iter.remove ();
-
- last_iter = null;
- last_position = uint.MAX;
- }
-
- public void remove_all () {
- data.get_begin_iter ().remove_range (data.get_end_iter ());
- unselect_all ();
-
- last_iter = null;
- last_position = uint.MAX;
- }
-
- public void set_sort_func (GLib.CompareDataFunc function) {
- this.compare_func = function;
- }
-
- public void set_filter_func (RowVisibilityFunc? function) {
- filter_func = function;
- }
-}
diff --git a/src/Layouts/FillsList/FillsPanel.vala b/src/Layouts/FillsList/FillsPanel.vala
deleted file mode 100644
index 843293b21..000000000
--- a/src/Layouts/FillsList/FillsPanel.vala
+++ /dev/null
@@ -1,101 +0,0 @@
-/**
- * Copyright (c) 2022 Alecaddd (https://alecaddd.com)
- *
- * This file is part of Akira.
- *
- * Akira 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.
-
- * Akira 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 Akira. If not, see .
- *
- * Authored by: Alessandro "alecaddd" Castellani
- */
-
-public class Akira.Layouts.FillsList.FillsPanel : Gtk.Grid {
- public unowned Akira.Lib.ViewCanvas view_canvas { get; construct; }
-
- public FillListBox fills_listbox;
-
- public FillsPanel (Akira.Lib.ViewCanvas canvas) {
- Object (
- view_canvas: canvas
- );
-
- var title_cont = new Gtk.Grid () {
- orientation = Gtk.Orientation.HORIZONTAL,
- hexpand = true
- };
- title_cont.get_style_context ().add_class ("option-panel");
-
- var label = new Gtk.Label (_("Fills")) {
- halign = Gtk.Align.FILL,
- xalign = 0,
- hexpand = true,
- ellipsize = Pango.EllipsizeMode.END
- };
-
- var add_btn = new Gtk.Button.from_icon_name ("list-add-symbolic", Gtk.IconSize.SMALL_TOOLBAR) {
- can_focus = false,
- valign = Gtk.Align.CENTER,
- halign = Gtk.Align.CENTER,
- tooltip_text = _("Add fill color")
- };
- add_btn.clicked.connect (add_fill);
- add_btn.get_style_context ().add_class (Gtk.STYLE_CLASS_FLAT);
-
- title_cont.attach (label, 0, 0, 1, 1);
- title_cont.attach (add_btn, 1, 0, 1, 1);
-
- attach (title_cont, 0, 0, 1, 1);
-
- fills_listbox = new FillListBox (view_canvas);
- attach (fills_listbox, 0, 1, 1, 1);
-
- // Show the widget by default.
- show_all ();
- // But then hide it right after so we can toggle it.
- visible = false;
- no_show_all = true;
-
- view_canvas.window.event_bus.selection_modified.connect (on_selection_modified);
- }
-
- private void on_selection_modified () {
- unowned var sm = view_canvas.selection_manager;
- bool is_visible = sm.count () > 0;
-
- visible = is_visible;
- no_show_all = !is_visible;
-
- fills_listbox.refresh_list ();
- }
-
- private void add_fill () {
- unowned var sm = view_canvas.selection_manager;
- if (sm.count () == 0) {
- return;
- }
-
- var fill_rgba = Gdk.RGBA ();
- fill_rgba.parse (settings.fill_color);
- var color = Lib.Components.Color.from_rgba (fill_rgba);
-
- unowned var im = _view_canvas.items_manager;
- foreach (var selected in sm.selection.nodes.values) {
- var new_fills = selected.node.instance.components.fills.copy ();
- new_fills.append_fill_with_color (color);
- selected.node.instance.components.fills = new_fills;
- im.item_model.alert_node_changed (selected.node, Lib.Components.Component.Type.COMPILED_FILL);
- }
- im.compile_model ();
- fills_listbox.refresh_list ();
- }
-}
diff --git a/src/Layouts/HeaderBar.vala b/src/Layouts/HeaderBar.vala
deleted file mode 100644
index e6c02a63c..000000000
--- a/src/Layouts/HeaderBar.vala
+++ /dev/null
@@ -1,592 +0,0 @@
-/*
- * Copyright (c) 2019-2020 Alecaddd (https://alecaddd.com)
- *
- * This file is part of Akira.
- *
- * Akira 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.
-
- * Akira 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 Akira. If not, see .
- *
- * Authored by: Alessandro "Alecaddd" Castellani
- */
-
-public class Akira.Layouts.HeaderBar : Gtk.HeaderBar {
- public weak Akira.Window window { get; construct; }
-
- public Widgets.HeaderBarButton new_document;
- public Widgets.HeaderBarButton save_file;
- public Widgets.HeaderBarButton save_file_as;
- public Gtk.Grid recent_files_grid;
-
- public Widgets.MenuButton menu;
- public Widgets.MenuButton items;
- public Widgets.ZoomButton zoom;
- public Widgets.HeaderBarButton group;
- public Widgets.HeaderBarButton ungroup;
- public Widgets.HeaderBarButton move_up;
- public Widgets.HeaderBarButton move_down;
- public Widgets.HeaderBarButton move_top;
- public Widgets.HeaderBarButton move_bottom;
- public Widgets.HeaderBarButton preferences;
- public Widgets.HeaderBarButton path_difference;
- public Widgets.HeaderBarButton path_exclusion;
- public Widgets.HeaderBarButton path_intersect;
- public Widgets.HeaderBarButton path_union;
-
- public Gtk.PopoverMenu popover_insert;
-
- public bool toggled {
- get {
- return visible;
- } set {
- visible = value;
- no_show_all = !value;
- }
- }
-
- public HeaderBar (Akira.Window window) {
- Object (
- toggled: true,
- window: window
- );
- }
-
- construct {
- set_show_close_button (true);
- set_project_title ( _("Untitled") );
-
- menu = new Widgets.MenuButton ("document-open", _("Menu"), null);
- var menu_popover = build_main_menu_popover ();
- menu.button.popover = menu_popover;
-
- items = new Widgets.MenuButton ("insert-object", _("Insert"), null);
- var items_popover = build_items_popover ();
- items.button.popover = items_popover;
-
- zoom = new Widgets.ZoomButton (window);
-
- group =new Widgets.HeaderBarButton (window, "object-group",
- _("Group"), {"g"}, "multiple");
- ungroup = new Widgets.HeaderBarButton (window, "object-ungroup",
- _("Ungroup"), {"g"}, "group");
-
- move_up = new Widgets.HeaderBarButton (window, "selection-raise",
- _("Up"), {"Up"}, "single");
- move_up.button.action_name = Akira.Services.ActionManager.ACTION_PREFIX
- + Akira.Services.ActionManager.ACTION_MOVE_UP;
-
- move_down = new Widgets.HeaderBarButton (window, "selection-lower",
- _("Down"), {"Down"}, "single");
- move_down.button.action_name = Akira.Services.ActionManager.ACTION_PREFIX
- + Akira.Services.ActionManager.ACTION_MOVE_DOWN;
-
- move_top = new Widgets.HeaderBarButton (window, "selection-top",
- _("Top"), {"Up"}, "single");
- move_top.button.action_name = Akira.Services.ActionManager.ACTION_PREFIX
- + Akira.Services.ActionManager.ACTION_MOVE_TOP;
-
- move_bottom = new Widgets.HeaderBarButton (window, "selection-bottom",
- _("Bottom"), {"Down"}, "single");
- move_bottom.button.action_name = Akira.Services.ActionManager.ACTION_PREFIX
- + Akira.Services.ActionManager.ACTION_MOVE_BOTTOM;
-
- preferences = new Widgets.HeaderBarButton (window, "open-menu",
- _("Settings"), {"comma"});
- preferences.button.action_name = Akira.Services.ActionManager.ACTION_PREFIX
- + Akira.Services.ActionManager.ACTION_PREFERENCES;
- preferences.sensitive = true;
-
- var export = new Widgets.MenuButton ("document-export", _("Export"), null);
- var export_popover = build_export_popover ();
- export.button.popover = export_popover;
- export.sensitive = true;
-
- var layout = new Widgets.MenuButton ("document-layout", _("Layout"), null);
- var layout_popover = build_layout_popover ();
- layout.button.popover = layout_popover;
- layout.sensitive = true;
-
- path_difference = new Widgets.HeaderBarButton (window, "path-difference",
- _("Difference"), null, "multiple");
- path_exclusion = new Widgets.HeaderBarButton (window, "path-exclusion",
- _("Exclusion"), null, "multiple");
- path_intersect = new Widgets.HeaderBarButton (window, "path-intersection",
- _("Intersect"), null, "multiple");
- path_union = new Widgets.HeaderBarButton (window, "path-union",
- _("Union"), null, "multiple");
-
- pack_start (menu);
- pack_start (items);
- pack_start (new Gtk.Separator (Gtk.Orientation.VERTICAL));
- pack_start (zoom);
- pack_start (new Gtk.Separator (Gtk.Orientation.VERTICAL));
- pack_start (group);
- pack_start (ungroup);
- pack_start (new Gtk.Separator (Gtk.Orientation.VERTICAL));
- pack_start (move_up);
- pack_start (move_down);
- pack_start (move_top);
- pack_start (move_bottom);
-
- pack_end (preferences);
- pack_end (layout);
- pack_end (export);
- pack_end (new Gtk.Separator (Gtk.Orientation.VERTICAL));
- pack_end (path_difference);
- pack_end (path_exclusion);
- pack_end (path_intersect);
- pack_end (path_union);
-
- build_signals ();
- }
-
- private Gtk.PopoverMenu build_main_menu_popover () {
- var grid = new Gtk.Grid ();
- grid.margin_top = 6;
- grid.margin_bottom = 3;
- grid.orientation = Gtk.Orientation.VERTICAL;
- grid.width_request = 240;
- grid.name = "main";
-
- var new_window_button = create_model_button (
- _("New Window"),
- "window-new-symbolic",
- Akira.Services.ActionManager.ACTION_PREFIX
- + Akira.Services.ActionManager.ACTION_NEW_WINDOW);
-
- var separator = new Gtk.Separator (Gtk.Orientation.HORIZONTAL);
- separator.margin_top = separator.margin_bottom = 3;
-
- var open_button = create_model_button (
- _("Open"),
- "document-open-symbolic",
- Akira.Services.ActionManager.ACTION_PREFIX + Akira.Services.ActionManager.ACTION_OPEN);
-
- recent_files_grid = new Gtk.Grid ();
- recent_files_grid.margin_top = 6;
- recent_files_grid.margin_bottom = 3;
- recent_files_grid.orientation = Gtk.Orientation.VERTICAL;
- recent_files_grid.width_request = 220;
- recent_files_grid.name = "files-menu";
-
- var open_recent_button = new Gtk.ModelButton ();
- open_recent_button.text = _("Open Recent");
- open_recent_button.menu_name = "files-menu";
- fetch_recent_files.begin ();
-
- var separator2 = new Gtk.Separator (Gtk.Orientation.HORIZONTAL);
- separator2.margin_top = separator2.margin_bottom = 3;
-
- var save_button = create_model_button (
- _("Save"),
- "document-save-symbolic",
- Akira.Services.ActionManager.ACTION_PREFIX + Akira.Services.ActionManager.ACTION_SAVE);
-
- var save_as_button = create_model_button (
- _("Save As"),
- "document-save-as-symbolic",
- Akira.Services.ActionManager.ACTION_PREFIX
- + Akira.Services.ActionManager.ACTION_SAVE_AS);
-
- var separator3 = new Gtk.Separator (Gtk.Orientation.HORIZONTAL);
- separator3.margin_top = separator3.margin_bottom = 3;
-
- var quit_button = create_model_button (
- _("Quit"),
- "system-shutdown-symbolic",
- Akira.Services.ActionManager.ACTION_PREFIX + Akira.Services.ActionManager.ACTION_QUIT);
-
- grid.add (new_window_button);
- grid.add (separator);
- grid.add (open_button);
- grid.add (open_recent_button);
- grid.add (separator2);
- grid.add (save_button);
- grid.add (save_as_button);
- grid.add (separator3);
- grid.add (quit_button);
- grid.show_all ();
-
- var popover = new Gtk.PopoverMenu ();
- popover.add (grid);
- popover.add (recent_files_grid);
- popover.child_set_property (grid, "submenu", "main");
- popover.child_set_property (recent_files_grid, "submenu", "files-menu");
-
- return popover;
- }
-
- private Gtk.PopoverMenu build_items_popover () {
- var grid = new Gtk.Grid ();
- grid.margin_top = 6;
- grid.margin_bottom = 3;
- grid.orientation = Gtk.Orientation.VERTICAL;
- grid.width_request = 200;
- grid.name = "main";
-
- var artboard = create_model_button (
- _("Artboard"),
- "window-new-symbolic",
- Akira.Services.ActionManager.ACTION_PREFIX
- + Akira.Services.ActionManager.ACTION_ARTBOARD_TOOL);
-
- var separator = new Gtk.Separator (Gtk.Orientation.HORIZONTAL);
- separator.margin_top = separator.margin_bottom = 3;
-
- // Create the shapes submenu
- var shapes_grid = new Gtk.Grid ();
- shapes_grid.margin_top = 6;
- shapes_grid.margin_bottom = 3;
- shapes_grid.orientation = Gtk.Orientation.VERTICAL;
- shapes_grid.width_request = 200;
- shapes_grid.name = "shapes-menu";
-
- var back_button = new Gtk.ModelButton ();
- back_button.text = _("Add Items");
- back_button.inverted = true;
- back_button.menu_name = "main";
-
- var sub_separator = new Gtk.Separator (Gtk.Orientation.HORIZONTAL);
- sub_separator.margin_top = sub_separator.margin_bottom = 3;
-
- var rectangle = create_model_button (
- _("Rectangle"),
- "shape-rectangle-symbolic",
- Akira.Services.ActionManager.ACTION_PREFIX +
- Akira.Services.ActionManager.ACTION_RECT_TOOL);
-
- var ellipse = create_model_button (
- _("Ellipse"),
- "shape-circle-symbolic",
- Akira.Services.ActionManager.ACTION_PREFIX +
- Akira.Services.ActionManager.ACTION_ELLIPSE_TOOL);
-
- shapes_grid.add (back_button);
- shapes_grid.add (sub_separator);
- shapes_grid.add (rectangle);
- shapes_grid.add (ellipse);
- shapes_grid.show_all ();
-
- var shapes_button = new Gtk.ModelButton ();
- shapes_button.text = _("Shapes");
- shapes_button.menu_name = "shapes-menu";
-
- var separator2 = new Gtk.Separator (Gtk.Orientation.HORIZONTAL);
- separator2.margin_top = separator2.margin_bottom = 3;
-
- var vector = create_model_button (
- _("Vector"),
- "segment-curve",
- Akira.Services.ActionManager.ACTION_PREFIX +
- Akira.Services.ActionManager.ACTION_PATH_TOOL);
-
- var pencil = create_model_button (_("Pencil"), "edit-symbolic", "P");
-
- var text = create_model_button (
- _("Text"),
- "shape-text-symbolic",
- Akira.Services.ActionManager.ACTION_PREFIX +
- Akira.Services.ActionManager.ACTION_TEXT_TOOL);
-
- var image = create_model_button (
- _("Image"),
- "image-x-generic-symbolic",
- Akira.Services.ActionManager.ACTION_PREFIX +
- Akira.Services.ActionManager.ACTION_IMAGE_TOOL);
-
- grid.add (artboard);
- grid.add (separator);
- grid.add (shapes_button);
- grid.add (separator2);
- grid.add (vector);
- grid.add (pencil);
- grid.add (text);
- grid.add (image);
- grid.show_all ();
-
- popover_insert = new Gtk.PopoverMenu ();
- popover_insert.add (grid);
- popover_insert.add (shapes_grid);
- popover_insert.child_set_property (grid, "submenu", "main");
- popover_insert.child_set_property (shapes_grid, "submenu", "shapes-menu");
-
- return popover_insert;
- }
-
- private Gtk.PopoverMenu build_export_popover () {
- var grid = new Gtk.Grid ();
- grid.margin_top = 6;
- grid.margin_bottom = 3;
- grid.orientation = Gtk.Orientation.VERTICAL;
- grid.width_request = 240;
- grid.name = "main";
-
- var export_selection = create_model_button (
- _("Export Current Selection"),
- null,
- Akira.Services.ActionManager.ACTION_PREFIX
- + Akira.Services.ActionManager.ACTION_EXPORT_SELECTION);
-
- var export_artboards = create_model_button (
- _("Export Artboards"),
- null,
- Akira.Services.ActionManager.ACTION_PREFIX
- + Akira.Services.ActionManager.ACTION_EXPORT_ARTBOARDS);
-
- var separator = new Gtk.Separator (Gtk.Orientation.HORIZONTAL);
- separator.margin_top = separator.margin_bottom = 3;
-
- var export_area_grab = create_model_button (
- _("Highlight Area to Export"),
- null,
- Akira.Services.ActionManager.ACTION_PREFIX
- + Akira.Services.ActionManager.ACTION_EXPORT_GRAB
- );
-
- grid.add (export_selection);
- grid.add (export_artboards);
- grid.add (separator);
- grid.add (export_area_grab);
- grid.show_all ();
-
- var popover = new Gtk.PopoverMenu ();
- popover.add (grid);
-
- return popover;
- }
-
- private Gtk.PopoverMenu build_layout_popover () {
- var grid = new Gtk.Grid ();
- grid.margin_top = 6;
- grid.margin_bottom = 3;
- grid.orientation = Gtk.Orientation.VERTICAL;
- grid.width_request = 240;
- grid.name = "main";
-
- var pixel_grid = create_model_button (
- _("Toggle Pixel Grid"),
- null,
- Akira.Services.ActionManager.ACTION_PREFIX
- + Akira.Services.ActionManager.ACTION_TOGGLE_PIXEL_GRID);
-
- var presentation_mode = create_model_button (
- _("Presentation Mode"),
- null,
- Akira.Services.ActionManager.ACTION_PREFIX
- + Akira.Services.ActionManager.ACTION_PRESENTATION);
-
- grid.add (pixel_grid);
- grid.add (presentation_mode);
- grid.show_all ();
-
- var popover = new Gtk.PopoverMenu ();
- popover.add (grid);
-
- return popover;
- }
-
- private void build_signals () {
- window.event_bus.toggle_presentation_mode.connect (toggle);
- window.event_bus.file_edited.connect (on_file_edited);
- window.event_bus.file_saved.connect (on_file_saved);
- window.event_bus.selection_modified.connect (on_selection_modified);
- window.event_bus.update_recent_files_list.connect (fetch_recent_files);
- }
-
- private void toggle () {
- toggled = !toggled;
- if (!toggled) {
- window.event_bus.canvas_notification (_("Presentation Mode enabled."));
- }
- }
-
- /**
- * Fetch the recently opened files from GSettings and add them to the list
- * if those files still exists.
- */
- public async void fetch_recent_files () {
- recent_files_grid.@foreach (child => {
- recent_files_grid.remove (child);
- });
-
- // Add default buttons.
- var back_button = new Gtk.ModelButton ();
- back_button.text = _("Main Menu");
- back_button.inverted = true;
- back_button.menu_name = "main";
- back_button.expand = true;
-
- var sub_separator = new Gtk.Separator (Gtk.Orientation.HORIZONTAL);
- sub_separator.margin_top = sub_separator.margin_bottom = 3;
-
- recent_files_grid.add (back_button);
- recent_files_grid.add (sub_separator);
-
- // Loop a first time to clear missing files and prevent wrong accelerators.
- string[] all_files = {};
- for (var i = 0; i <= settings.recently_opened.length; i++) {
- // Skip if the record is empty.
- if (settings.recently_opened[i] == null) {
- continue;
- }
-
- // Skip if the file doesn't exist.
- var file = File.new_for_path (settings.recently_opened[i]);
- if (!file.query_exists ()) {
- continue;
- }
-
- all_files += settings.recently_opened[i];
- }
-
- // Update the GSettings to prevent loading an unavailable file.
- settings.set_strv ("recently-opened", all_files);
-
- for (var i = 0; i <= all_files.length; i++) {
- // Skip if the record is empty.
- if (all_files[i] == null) {
- continue;
- }
-
- // Store the full path in a variable before the split() method explodes the string.
- var full_path = all_files[i];
-
- // Get the file name.
- string[] split_string = all_files[i].split ("/");
- var file_name = split_string[split_string.length - 1].replace (".akira", "");
-
- var button = new Gtk.ModelButton ();
-
- // Add quick accelerators only for the first 3 items.
- string? accels = null;
- if (i < 3) {
- switch (i) {
- case 0:
- accels = Akira.Services.ActionManager.ACTION_PREFIX
- + Akira.Services.ActionManager.ACTION_LOAD_FIRST;
- break;
- case 1:
- accels = Akira.Services.ActionManager.ACTION_PREFIX
- + Akira.Services.ActionManager.ACTION_LOAD_SECOND;
- break;
- case 2:
- accels = Akira.Services.ActionManager.ACTION_PREFIX
- + Akira.Services.ActionManager.ACTION_LOAD_THIRD;
- break;
- }
-
- button.get_child ().destroy ();
- var label = new Granite.AccelLabel.from_action_name (file_name, accels);
- button.add (label);
- button.action_name = accels;
- } else {
- button.text = file_name;
-
- // Define the open action on click only for those files that don't
- // have an accelerator to prevent double calls.
- button.clicked.connect (() => {
- var file = File.new_for_path (full_path);
- if (!file.query_exists ()) {
- window.event_bus.canvas_notification (
- _("Unable to open file at '%s'").printf (full_path)
- );
- return;
- }
-
- File[] files = {};
- files += file;
- window.app.open (files, "");
- });
- }
-
- button.tooltip_text = all_files[i];
-
- recent_files_grid.add (button);
- }
-
- recent_files_grid.show_all ();
- }
-
- private void on_file_edited () {
- if (title.has_suffix ("*")) {
- return;
- }
-
- title = ("%s*").printf (title);
- }
-
- private void on_file_saved (string? file_name) {
- if (file_name == null) {
- title = title.has_suffix ("*") ? title.slice (0, title.length - 1) : title;
- return;
- }
-
- title = file_name.has_suffix (".akira") ? file_name.replace (".akira", "") : file_name;
- }
-
- private void on_selection_modified () {
- unowned var sm = window.main_window.main_view_canvas.canvas.selection_manager;
- var count = sm.count ();
-
- if (count == 0) {
- move_up.sensitive = false;
- move_down.sensitive = false;
- move_top.sensitive = false;
- move_bottom.sensitive = false;
- } else if (count > 1) {
- move_up.sensitive = true;
- move_down.sensitive = true;
- move_top.sensitive = true;
- move_bottom.sensitive = true;
- } else {
- var node = sm.selection.first_node ();
- bool is_top = node.parent.children.length - 1 == node.pos_in_parent;
- bool is_bottom = node.pos_in_parent == 0;
-
- move_up.sensitive = !is_top;
- move_down.sensitive = !is_bottom;
- move_top.sensitive = !is_top;
- move_bottom.sensitive = !is_bottom;
- }
- }
-
- private Gtk.ModelButton create_model_button (string text, string? icon, string? accels = null) {
- var button = new Gtk.ModelButton ();
- button.get_child ().destroy ();
- var label = new Granite.AccelLabel.from_action_name (text, accels);
-
- if (icon != null) {
- var image = new Gtk.Image.from_icon_name (icon, Gtk.IconSize.MENU);
- image.margin_end = 6;
- label.attach_next_to (
- image,
- label.get_child_at (0, 0),
- Gtk.PositionType.LEFT
- );
- }
-
- button.add (label);
- button.action_name = accels;
-
- return button;
- }
-
- private void set_project_title (string title) {
- this.title = title;
- Gtk.Label label = new Gtk.Label (title);
- label.get_style_context ().add_class (Gtk.STYLE_CLASS_TITLE);
- label.set_hexpand (true);
- label.set_ellipsize (Pango.EllipsizeMode.END);
-
- set_custom_title (label);
- }
-}
diff --git a/src/Layouts/LayersList/LayerItemModel.vala b/src/Layouts/LayersList/LayerItemModel.vala
deleted file mode 100644
index 0e394a9c0..000000000
--- a/src/Layouts/LayersList/LayerItemModel.vala
+++ /dev/null
@@ -1,195 +0,0 @@
-/*
- * Copyright (c) 2021 Alecaddd (https://alecaddd.com)
- *
- * This file is part of Akira.
- *
- * Akira 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.
-
- * Akira 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 Akira. If not, see .
- *
- * Authored by: Alessandro "Alecaddd" Castellani
- * Adapted from the elementary OS Mail's VirtualizingListBox source code created
- * by David Hewitt
- */
-
-/*
- * Simple Object to be handled by the LayersListBoxModel and to give easy access
- * the attributes of the Lib.Items.ModelNode.
- */
-public class Akira.Layouts.LayersList.LayerItemModel : GLib.Object {
- private unowned Akira.Lib.ViewCanvas _view_canvas;
-
- private Lib.Items.ModelInstance _cached_instance;
-
- public int id {
- get {
- return _cached_instance.id;
- }
- }
- /*
- * Control the name of the item.
- */
- public string name {
- owned get {
- return _cached_instance.components.name.name;
- }
- set {
- if (_cached_instance.components.name.name == value) {
- return;
- }
-
- unowned var im = _view_canvas.items_manager;
- var node = im.item_model.node_from_id (_cached_instance.id);
- assert (node != null);
-
- node.instance.components.name = new Lib.Components.Name (value, id.to_string ());
- im.item_model.alert_node_changed (node, Lib.Components.Component.Type.COMPILED_NAME);
- im.compile_model ();
- }
- }
-
- public string icon {
- get {
- unowned var type = _cached_instance.type;
- if (type is Lib.Items.ModelTypeRect) {
- return "shape-rectangle-symbolic";
- } else if (type is Lib.Items.ModelTypeEllipse) {
- return "shape-circle-symbolic";
- } else if (type is Lib.Items.ModelTypePath) {
- return "segment-curve-symbolic";
- } else if (type is Lib.Items.ModelTypeGroup) {
- return "folder-symbolic";
- } else if (type is Lib.Items.ModelTypeText) {
- return "shape-text-symbolic";
- }
- return "";
- }
- }
-
- /*
- * Control the hidden/visible state of the item.
- */
- // TODO.
-
- /*
- * Control the locked/unlocked state of the item.
- */
- public bool locked {
- get {
- return _cached_instance.components.layer.locked;
- }
- set {
- if (_cached_instance.components.layer.locked == value) {
- return;
- }
-
- // If the layer is being locked we need to remove it from the
- // current selection if needed.
- if (value) {
- unowned var sm = _view_canvas.selection_manager;
- sm.remove_from_selection (id);
- sm.selection_modified_external ();
- }
-
- unowned var im = _view_canvas.items_manager;
- var node = im.item_model.node_from_id (_cached_instance.id);
- assert (node != null);
-
- node.instance.components.layer = new Lib.Components.Layer (value);
- // If the layer is a group we need to update the locked state on
- // all of its children.
- if (node.children != null) {
- _view_canvas.window.main_window.set_children_locked (node.get_children_ids (), value);
- }
- }
- }
-
- /*
- * If the instance type is an Artboard.
- */
- public bool is_artboard {
- get {
- return _cached_instance.is_artboard;
- }
- }
-
- /*
- * If the instance type is a Group.
- */
- public bool is_group {
- get {
- return _cached_instance.is_group;
- }
- }
-
- public int[] get_children () {
- return _cached_instance.children;
- }
-
- public int parent_uid {
- get {
- unowned var im = _view_canvas.items_manager;
- var node = im.item_model.node_from_id (_cached_instance.id);
- assert (node != null);
-
- return node.parent.id;
- }
- }
-
- public int ancestors_size {
- get {
- unowned var im = _view_canvas.items_manager;
- var node = im.item_model.node_from_id (_cached_instance.id);
- assert (node != null);
-
- return node.get_ancestors_size ();
- }
- }
-
- // Always show child layers when a new artboard or group is created.
- private bool _children_visible = true;
- public bool children_visible {
- get {
- return _children_visible;
- }
- set {
- if (value == _children_visible) {
- return;
- }
- _children_visible = value;
-
- // No need to update the layers UI if this model is not a group or
- // an artboard.
- if (!is_group && !is_artboard) {
- return;
- }
-
- var array = new GLib.Array ();
- array.data = get_children ();
- // Trigger the showing or hiding of all child layers.
- if (_children_visible) {
- _view_canvas.window.main_window.add_layers (array);
- } else {
- _view_canvas.window.main_window.remove_layers (array);
- }
- }
- }
-
- public LayerItemModel (Lib.ViewCanvas view_canvas, Lib.Items.ModelNode node) {
- update_node (node);
- _view_canvas = view_canvas;
- }
-
- private void update_node (Lib.Items.ModelNode new_node) {
- _cached_instance = new_node.instance;
- }
-}
diff --git a/src/Layouts/LayersList/LayerListBox.vala b/src/Layouts/LayersList/LayerListBox.vala
deleted file mode 100644
index 094a035b6..000000000
--- a/src/Layouts/LayersList/LayerListBox.vala
+++ /dev/null
@@ -1,508 +0,0 @@
-/*
- * Copyright (c) 2021 Alecaddd (https://alecaddd.com)
- *
- * This file is part of Akira.
- *
- * Akira 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.
-
- * Akira 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 Akira. If not, see .
- *
- * Authored by: Alessandro "Alecaddd" Castellani
- * Adapted from the elementary OS Mail's VirtualizingListBox source code created
- * by David Hewitt
- */
-
-/*
- * The scrollable layers panel.
- */
-public class Akira.Layouts.LayersList.LayerListBox : VirtualizingListBox {
- public unowned Akira.Lib.ViewCanvas view_canvas { get; construct; }
-
- private Gee.HashMap layers;
- private LayerListStore list_store;
-
- public LayerListBox (Akira.Lib.ViewCanvas canvas) {
- Object (
- view_canvas: canvas
- );
-
- selection_mode = Gtk.SelectionMode.MULTIPLE;
- activate_on_single_click = true;
- edit_on_double_click = true;
- layers = new Gee.HashMap ();
- list_store = new LayerListStore ();
- list_store.set_sort_func (layers_sort_function);
-
- model = list_store;
-
- // Factory function to reuse the already generated row UI element when
- // a new layer is created or the layers list scrolls to reveal layers
- // outside of the viewport.
- factory_func = (item, old_widget) => {
- LayerListItem? row = null;
- if (old_widget != null) {
- row = old_widget as LayerListItem;
- if (row.is_editing) {
- row.edit_end ();
- }
- } else {
- row = new LayerListItem ();
- }
-
- row.assign ((LayerItemModel) item);
- row.show_all ();
-
- return row;
- };
-
- // When an item is selected from a click on the layers list.
- row_selection_changed.connect (on_row_selection_changed);
-
- // When a row is hovered.
- row_hovered.connect (on_row_hovered);
-
- // When the name of the layer is being edited.
- row_edited.connect (on_row_edited);
-
- // Listen to the button release event only for the secondary click in
- // order to trigger the context menu.
- button_release_event.connect (e => {
- if (e.button != Gdk.BUTTON_SECONDARY) {
- return Gdk.EVENT_PROPAGATE;
- }
- var row = get_row_at_y ((int)e.y);
- if (row == null) {
- return Gdk.EVENT_PROPAGATE;
- }
-
- if (selected_row_widget != row) {
- select_row (row);
- }
- return create_context_menu (e, (LayerListItem)row);
- });
-
- // Trigger the context menu when the `menu` key is pressed.
- key_release_event.connect ((e) => {
- if (e.keyval != Gdk.Key.Menu) {
- return Gdk.EVENT_PROPAGATE;
- }
- var row = selected_row_widget;
- return create_context_menu (e, (LayerListItem)row);
- });
-
- view_canvas.items_manager.item_added.connect (on_item_added);
- view_canvas.selection_manager.selection_modified_external.connect (on_selection_modified_external);
- view_canvas.hover_manager.hover_changed.connect (on_hover_changed);
- view_canvas.window.event_bus.request_escape.connect (on_escape_request);
- }
-
- /*
- * Add all existing nodes to the layers list when the UI is revealed.
- */
- public void regenerate_list (bool go_to_layer) {
- unowned var im = view_canvas.items_manager;
-
- // Bail out if we don't have anything to add.
- if (im.item_model.group_nodes.size == 0 && im.item_model.item_nodes.size == 0) {
- return;
- }
-
- ulong microseconds;
- double seconds;
- // Create a timer object to track the regeneration of the layers list.
- Timer timer = new Timer ();
- var added = 0;
-
- foreach (var key in im.item_model.group_nodes.keys) {
- var node = im.item_model.group_nodes[key];
- if (node.id == Lib.Items.Model.ORIGIN_ID) {
- continue;
- }
- var item = new LayerItemModel (view_canvas, node);
- layers[node.id] = item;
- list_store.add (item);
- added++;
- }
-
- foreach (var key in im.item_model.item_nodes.keys) {
- var node = im.item_model.item_nodes[key];
- var item = new LayerItemModel (view_canvas, node);
- layers[node.id] = item;
- list_store.add (item);
- added++;
- }
-
- list_store.items_changed (0, 0, added);
-
- // Restore the selected items.
- on_selection_modified_external (go_to_layer);
-
- timer.stop ();
- seconds = timer.elapsed (out microseconds);
- print ("Created %i layers in %s s\n", added, seconds.to_string ());
- }
-
- /*
- * Clear the layers list when the UI is hidden.
- */
- public void clear_list () {
- // Interrupt if the layers list is empty.
- if (layers.size == 0) {
- return;
- }
-
- ulong microseconds;
- double seconds;
- // Create a timer object to track the deletion of the layers list.
- Timer timer = new Timer ();
-
- // Remove all items.
- var removed = layers.size;
- layers.clear ();
- list_store.remove_all ();
- list_store.items_changed (0, removed, 0);
-
- timer.stop ();
- seconds = timer.elapsed (out microseconds);
- print ("Deleted %i layers in %s s\n", removed, seconds.to_string ());
- }
-
- private void on_item_added (int id) {
- if (view_canvas.block_ui) {
- return;
- }
-
- var node = view_canvas.items_manager.node_from_id (id);
- // No need to add any layer if we don't have an instance.
- if (node == null) {
- return;
- }
-
- var node_id = node.id;
- var item = new LayerItemModel (view_canvas, node);
- layers[node_id] = item;
- list_store.add (item);
-
- // Check if the newly created layer is inside an artboard or a group and
- // show all its child layers if they were removed.
- recursive_show_child_layers (node_id);
- }
-
- private void recursive_show_child_layers (int node_id) {
- var item = layers[node_id];
- if (item == null) {
- return;
- }
-
- var parent = layers[item.parent_uid];
- if (parent == null) {
- return;
- }
-
- parent.children_visible = true;
- recursive_show_child_layers (parent.parent_uid);
- }
-
- private bool create_context_menu (Gdk.Event e, LayerListItem row) {
- var menu = new Gtk.Menu ();
- menu.show_all ();
-
- if (e.type == Gdk.EventType.BUTTON_RELEASE) {
- menu.popup_at_pointer (e);
- return Gdk.EVENT_STOP;
- } else if (e.type == Gdk.EventType.KEY_RELEASE) {
- menu.popup_at_widget (row, Gdk.Gravity.EAST, Gdk.Gravity.CENTER, e);
- return Gdk.EVENT_STOP;
- }
-
- return Gdk.EVENT_PROPAGATE;
- }
-
- /*
- * Visually create layers from a list of items ids. This method is used to
- * show layers that have been removed when a parent (artboard or group)
- * collapses its children.
- */
- public void add_items (GLib.Array ids) {
- if (view_canvas.block_ui) {
- return;
- }
-
- var added = 0;
- foreach (var uid in ids.data) {
- // Don't create a layer if it already exists. This might happen when
- // revealing the children of a collapsed artboard during the
- // creation of a new child item.
- if (layers[uid] == null) {
- on_item_added (uid);
- }
- // Check if the layer was actually created.
- if (layers[uid] != null) {
- added++;
- }
- }
- // Refresh the layers list UI.
- show_added_layers (added);
- }
-
- /*
- * Triggers the update of the list store and refresh of the UI to show the
- * newly added items that are currently visible.
- */
- public void show_added_layers (int added) {
- if (view_canvas.block_ui) {
- return;
- }
-
- list_store.items_changed (0, 0, added);
- // Restore selected items.
- on_selection_modified_external ();
- }
-
- /*
- * Remove all the currently selected layers. The list of ids comes from the
- * selected nodes in the view canvas.
- */
- public void remove_items (GLib.Array ids) {
- if (view_canvas.block_ui) {
- return;
- }
-
- var removed = 0;
- foreach (var uid in ids.data) {
- var item = layers[uid];
- if (item != null) {
- removed += inner_remove_items (item);
- layers.unset (uid);
- list_store.remove (item);
- removed++;
- }
- }
-
- list_store.items_changed (0, removed, 0);
- }
-
- /*
- * Check if an item has children and recursively loop through them to
- * remove all the matching layers.
- */
- private int inner_remove_items (LayerItemModel item) {
- var removed = 0;
- foreach (var uid in item.get_children ()) {
- if (uid == 0) {
- continue;
- }
-
- var child = layers[uid];
- if (child != null) {
- removed += inner_remove_items (child);
- layers.unset (uid);
- list_store.remove (child);
- removed++;
- }
- }
-
- return removed;
- }
-
- /*
- * Sort function to always add new layers at the top unless they belong to a
- * group or an artboard.
- */
- private int layers_sort_function (LayerItemModel layer1, LayerItemModel layer2) {
- var im = view_canvas.items_manager.item_model;
- var node1 = im.node_from_id (layer1.id);
- var node2 = im.node_from_id (layer2.id);
-
- var node1_is_group = node1.instance.is_group;
- var node2_is_group = node2.instance.is_group;
-
- if (node1_is_group != node2_is_group) {
- unowned var group_node = node1_is_group ? node1 : node2;
- unowned var child_node = node1_is_group ? node2 : node1;
- if (child_node.has_ancestor (group_node.id)) {
- return node1_is_group ? -1 : 1;
- }
- }
-
- var path1 = im.array_path_from_node (node1);
- var path2 = im.array_path_from_node (node2);
-
- return Utils.Array.compare_arrays (path2, path1);
- }
-
- /*
- * Update the selected items in the canvas when the selection of rows in the
- * listbox changes.
- */
- private void on_row_selection_changed (bool clear) {
- unowned var sm = view_canvas.selection_manager;
- // Always reset the selection.
- sm.reset_selection ();
-
- // No need to do anything else if all rows were deselected.
- if (clear) {
- reset_edited_row ();
- return;
- }
-
- var blocker = new Lib.Managers.SelectionManager.ChangeSignalBlocker (view_canvas.selection_manager);
- (blocker);
-
- // Add all currently selected rows to the selection. This won't trigger
- // a selection changed loop since the selection_modified_external signal
- // is only triggered from a click on the canvas.
- foreach (var model in get_selected_rows ()) {
- sm.add_to_selection (((LayerItemModel) model).id);
- }
-
- // Trigger the transform mode if is not currently active. This might
- // happen when no items is selected and the first selection is triggered
- // from the layers listbox.
- unowned var mm = view_canvas.mode_manager;
- if (mm.active_mode_type != Lib.Modes.AbstractInteractionMode.ModeType.TRANSFORM) {
- var new_mode = new Lib.Modes.TransformMode (view_canvas, Utils.Nobs.Nob.NONE, true);
- mm.register_mode (new_mode);
- mm.deregister_active_mode ();
- }
- }
-
- /*
- * When an item in the canvas is selected via click interaction.
- */
- private void on_selection_modified_external (bool go_to_layer = false) {
- reset_edited_row ();
-
- // Always reset the selection of the layers.
- unselect_all ();
-
- unowned var sm = view_canvas.selection_manager;
- if (sm.is_empty ()) {
- return;
- }
-
- var it = sm.selection.nodes.map_iterator ();
-
- // If the selection was modified from a click on the canvas, we need to
- // move the first selected layer into the viewport of the layers list.
- if (go_to_layer) {
- it.next ();
- var first_node = it.get_value ().node;
- if (layers[first_node.id] != null) {
- select_row_at_index (model.get_index_of (layers[first_node.id]));
- }
- }
-
- // For all other scenarios where a selection is restored dynamically or
- // multiple items are selected, we don't generate the layer row widgets
- // but we only update the selection state of the model.
- while (it.next ()) {
- var node = it.get_value ().node;
- if (layers[node.id] != null) {
- list_store.set_item_selected (layers[node.id], true);
- }
- }
-
- if (sm.selection.count () > 1) {
- // Trigger a visual refresh of the visible layers without changing
- // anything in the list store in order to show the newly selected layers.
- list_store.items_changed (0, 0, 0);
- }
- }
-
- /*
- * Show the hover effect on a canvas item if available.
- */
- private void on_row_hovered (GLib.Object? item) {
- unowned var hm = view_canvas.hover_manager;
- if (item == null) {
- hm.remove_hover_effect ();
- return;
- }
-
- hm.maybe_create_hover_effect_by_id (((LayerItemModel) item).id);
- }
-
- /*
- * Show the hover effect on a layer row when an item from the canvas is
- * hovered. Clear the hover effect if no canvas item was hovered.
- */
- private void on_hover_changed (int? id) {
- on_mouse_leave_internal ();
-
- if (id != null && layers[id] != null) {
- set_hover_on_row_from_model (layers[id]);
- }
- }
-
- /*
- * Toggle the edit state of rows and handle typing accelerators accordingly.
- */
- private void on_row_edited (VirtualizingListBoxRow? item) {
- reset_edited_row ();
-
- if (item == null) {
- return;
- }
-
- edited_row = item;
- var layer = (LayerListItem) edited_row;
- layer.edit ();
- layer.entry.activate.connect (on_activate_entry);
- view_canvas.window.event_bus.disconnect_typing_accel ();
- }
-
- /*
- * Handle the `activate` signal triggered by the edited label entry of a
- * layer row.
- */
- private void on_activate_entry () {
- ((LayerListItem) edited_row).update_label ();
- on_row_edited (null);
- }
-
- /*
- * If a layer row is currently being edited, reset it to the default state.
- */
- private void reset_edited_row () {
- if (edited_row != null) {
- var layer = (LayerListItem) edited_row;
- layer.edit_end ();
- layer.entry.activate.disconnect (on_activate_entry);
-
- edited_row = null;
- view_canvas.window.event_bus.connect_typing_accel ();
- }
- }
-
- /*
- * Be sure to reset any potential leftover edited layer row when the user
- * presses the `esc` button.
- */
- private void on_escape_request () {
- on_row_edited (null);
- }
-
- /*
- * Loop through the passed nodes and update the locked state.
- */
- public void set_children_locked (int[] nodes, bool is_locked) {
- foreach (var uid in nodes) {
- if (layers[uid] != null) {
- layers[uid].locked = is_locked;
- }
- }
- // Trigger a visual refresh of the visible layers without changing
- // anything in the list store.
- list_store.items_changed (0, 0, 0);
- }
-}
diff --git a/src/Layouts/LayersList/LayerListItem.vala b/src/Layouts/LayersList/LayerListItem.vala
deleted file mode 100644
index a54b14a59..000000000
--- a/src/Layouts/LayersList/LayerListItem.vala
+++ /dev/null
@@ -1,285 +0,0 @@
-/*
- * Copyright (c) 2021 Alecaddd (https://alecaddd.com)
- *
- * This file is part of Akira.
- *
- * Akira 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.
-
- * Akira 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 Akira. If not, see .
- *
- * Authored by: Alessandro "Alecaddd" Castellani
- * Adapted from the elementary OS Mail's VirtualizingListBox source code created
- * by David Hewitt
- */
-
-/*
- * The single layer row.
- */
-public class Akira.Layouts.LayersList.LayerListItem : VirtualizingListBoxRow {
- private LayerItemModel model;
-
- private Gtk.StyleContext style_ctx;
- // Main grid to attach all other grid widgets.
- private Gtk.Grid grid_main;
- // Grid to collect the label and entry widgets.
- private Gtk.Grid grid_entry;
- // Grid to collect the hide and lock action buttons.
- private Gtk.Grid grid_action;
-
- public Gtk.Entry entry;
- private Gtk.Label label;
- private Gtk.Image icon;
- private Gtk.Button btn_lock;
- private Gtk.Button btn_view;
- private Gtk.Button btn_toggle;
-
- private bool _is_editing = false;
- public bool is_editing {
- get {
- return _is_editing;
- }
- set {
- _is_editing = value;
- if (value) {
- grid_action.visible = false;
- return;
- }
-
- grid_action.visible = true;
- }
- }
-
- construct {
- style_ctx = get_style_context ();
-
- btn_toggle = new Gtk.Button.from_icon_name ("pan-down-symbolic", Gtk.IconSize.MENU) {
- tooltip_text = _("Toggle visibility of child layers"),
- can_focus = false
- };
- btn_toggle.clicked.connect (on_toggle_pressed);
- btn_toggle.get_style_context ().add_class ("flat");
- btn_toggle.get_style_context ().add_class ("button-toggle");
- btn_toggle.get_style_context ().add_class (Gtk.STYLE_CLASS_DIM_LABEL);
-
- icon = new Gtk.Image () {
- margin_end = 9,
- vexpand = true,
- valign = Gtk.Align.CENTER
- };
- icon.get_style_context ().add_class (Gtk.STYLE_CLASS_DIM_LABEL);
-
- label = new Gtk.Label (null) {
- halign = Gtk.Align.FILL,
- xalign = 0,
- expand = true,
- ellipsize = Pango.EllipsizeMode.END
- };
-
- grid_entry = new Gtk.Grid ();
- grid_entry.attach (label, 0, 0, 1, 1);
-
- btn_lock = new Gtk.Button.from_icon_name ("changes-allow-symbolic", Gtk.IconSize.MENU) {
- tooltip_text = _("Lock layer"),
- can_focus = false
- };
- btn_lock.clicked.connect (toggle_lock);
- btn_lock.get_style_context ().add_class ("flat");
-
- btn_view = new Gtk.Button.from_icon_name ("layer-visible-symbolic", Gtk.IconSize.MENU) {
- tooltip_text = _("Hide layer"),
- can_focus = false
- };
- btn_view.clicked.connect (toggle_view);
- btn_view.get_style_context ().add_class ("flat");
-
- grid_action = new Gtk.Grid () {
- margin_end = 6,
- vexpand = true,
- valign = Gtk.Align.CENTER
- };
- grid_action.get_style_context ().add_class ("actions");
- grid_action.attach (btn_lock, 0, 0, 1, 1);
- grid_action.attach (btn_view, 1, 0, 1, 1);
-
- grid_main = new Gtk.Grid () {
- vexpand = true,
- valign = Gtk.Align.CENTER
- };
- grid_main.attach (icon, 0, 0, 1, 1);
- grid_main.attach (btn_toggle, 1, 0, 1, 1);
- grid_main.attach (grid_entry, 2, 0, 1, 1);
- grid_main.attach (grid_action, 3, 0, 1, 1);
-
- add (grid_main);
- }
-
- public void assign (LayerItemModel data) {
- model_item = data;
- model = (LayerItemModel) model_item;
-
- label.label = model.name;
-
- // Build a specific UI based on the node instance's type.
- if (data.is_artboard) {
- build_artboard_ui ();
- } else if (data.is_group) {
- build_group_ui ();
- } else {
- build_layer_ui ();
- }
-
- // Update the state of the action buttons to reflect the model state.
- update_btn_lock ();
-
- // Indent child layers based on the amount of ancestors.
- grid_main.margin_start = 12 * model.ancestors_size;
- }
-
- private void build_artboard_ui () {
- // Update the general UI.
- style_ctx.remove_class ("layer");
- style_ctx.remove_class ("group");
- style_ctx.add_class ("artboard");
-
- // Update icon.
- icon.clear ();
- icon.margin_start = 0;
-
- // Show the toggle button.
- btn_toggle.no_show_all = false;
- btn_toggle.visible = true;
- update_btn_toggle ();
- }
-
- private void build_group_ui () {
- // Update the general UI.
- style_ctx.remove_class ("layer");
- style_ctx.remove_class ("artboard");
- style_ctx.add_class ("group");
-
- // Update icon.
- icon.clear ();
- icon.margin_start = 0;
-
- // Show the toggle button.
- btn_toggle.no_show_all = false;
- btn_toggle.visible = true;
-
- update_btn_toggle ();
- }
-
- private void build_layer_ui () {
- // Update general UI.
- style_ctx.remove_class ("artboard");
- style_ctx.remove_class ("group");
- style_ctx.add_class ("layer");
-
- // Update icon.
- icon.set_from_icon_name (model.icon, Gtk.IconSize.MENU);
- icon.margin_start = 12;
-
- // Hide the toggle button.
- btn_toggle.no_show_all = true;
- btn_toggle.visible = false;
- }
-
- public override void edit () {
- if (entry != null) {
- show_entry ();
- return;
- }
-
- entry = new Gtk.Entry () {
- expand = true,
- margin_end = 6
- };
- entry.get_style_context ().add_class ("flat");
-
- grid_entry.attach (entry, 0, 1, 1, 1);
-
- show_entry ();
- }
-
- /*
- * The user pressed `Enter` on the layer's entry, so we trigger the update
- * of the layer's name.
- */
- public void update_label () {
- // Trigger the model update.
- model.name = entry.text;
- // Update the visible label with the new model.name, so we're sure the
- // update took effect.
- label.label = model.name;
- }
-
- private void show_entry () {
- entry.text = label.label;
- entry.visible = true;
- entry.no_show_all = false;
- label.visible = false;
- label.no_show_all = true;
- entry.grab_focus ();
- is_editing = true;
- }
-
- public override void edit_end () {
- entry.visible = false;
- entry.no_show_all = true;
- label.visible = true;
- label.no_show_all = false;
- is_editing = false;
- }
-
- private void toggle_lock () {
- model.locked = !model.locked;
- update_btn_lock ();
- }
-
- private void update_btn_lock () {
- if (model.locked) {
- btn_lock.get_style_context ().add_class ("active");
- btn_lock.image = new Gtk.Image.from_icon_name ("changes-prevent-symbolic", Gtk.IconSize.MENU);
- btn_lock.tooltip_text = _("Unlock layer");
- selectable = false;
- } else {
- btn_lock.get_style_context ().remove_class ("active");
- btn_lock.image = new Gtk.Image.from_icon_name ("changes-allow-symbolic", Gtk.IconSize.MENU);
- btn_lock.tooltip_text = _("Lock layer");
- selectable = true;
- }
- }
-
- // TODO.
- private void toggle_view () {
- print ("view pressed\n");
- }
-
- /*
- * Hide or show the child layers of this layer when the user clicks on the
- * toggle button.
- */
- private void on_toggle_pressed () {
- model.children_visible = !model.children_visible;
- update_btn_toggle ();
- }
-
- /*
- * Visually update the toggle button.
- */
- private void update_btn_toggle () {
- if (model.children_visible) {
- btn_toggle.get_style_context ().remove_class ("collapsed");
- } else {
- btn_toggle.get_style_context ().add_class ("collapsed");
- }
- }
-}
diff --git a/src/Layouts/LayersList/LayerListStore.vala b/src/Layouts/LayersList/LayerListStore.vala
deleted file mode 100644
index 0b7c40c1e..000000000
--- a/src/Layouts/LayersList/LayerListStore.vala
+++ /dev/null
@@ -1,117 +0,0 @@
-/*
- * Copyright (c) 2021 Alecaddd (https://alecaddd.com)
- *
- * This file is part of Akira.
- *
- * Akira 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.
-
- * Akira 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 Akira. If not, see .
- *
- * Authored by: Alessandro "Alecaddd" Castellani
- * Adapted from the elementary OS Mail's VirtualizingListBox source code created
- * by David Hewitt
- */
-
-/*
- * The model holding the layers panel rows.
- */
-public class Akira.Layouts.LayersList.LayerListStore : VirtualizingListBoxModel {
- public delegate bool RowVisibilityFunc (GLib.Object row);
-
- private GLib.Sequence data = new GLib.Sequence ();
- private uint last_position = uint.MAX;
- private GLib.SequenceIter? last_iter;
- private unowned GLib.CompareDataFunc compare_func;
- private unowned RowVisibilityFunc filter_func;
-
- public override uint get_n_items () {
- return data.get_length ();
- }
-
- public override GLib.Object? get_item (uint index) {
- return get_item_internal (index);
- }
-
- public override GLib.Object? get_item_unfiltered (uint index) {
- return get_item_internal (index, true);
- }
-
- private GLib.Object? get_item_internal (uint index, bool unfiltered = false) {
- GLib.SequenceIter? iter = null;
-
- if (last_position != uint.MAX) {
- if (last_position == index + 1) {
- iter = last_iter.prev ();
- } else if (last_position == index - 1) {
- iter = last_iter.next ();
- } else if (last_position == index) {
- iter = last_iter;
- }
- }
-
- if (iter == null) {
- iter = data.get_iter_at_pos ((int)index);
- }
-
- last_iter = iter;
- last_position = index;
-
- if (iter.is_end ()) {
- return null;
- }
-
- if (filter_func == null) {
- return iter.get ();
- } else if (filter_func (iter.get ())) {
- return iter.get ();
- } else if (unfiltered) {
- return iter.get ();
- } else {
- return null;
- }
- }
-
- public void add (LayerItemModel model) {
- if (compare_func != null) {
- this.data.insert_sorted (model, compare_func);
- } else {
- this.data.prepend (model);
- }
-
- last_iter = null;
- last_position = uint.MAX;
- }
-
- public void remove (LayerItemModel data) {
- var iter = this.data.get_iter_at_pos (get_index_of_unfiltered (data));
- iter.remove ();
-
- last_iter = null;
- last_position = uint.MAX;
- }
-
- public void remove_all () {
- data.get_begin_iter ().remove_range (data.get_end_iter ());
- unselect_all ();
-
- last_iter = null;
- last_position = uint.MAX;
- }
-
- public void set_sort_func (GLib.CompareDataFunc function) {
- this.compare_func = function;
- }
-
- public void set_filter_func (RowVisibilityFunc? function) {
- filter_func = function;
- }
-}
diff --git a/src/Layouts/MainCanvas.vala b/src/Layouts/MainCanvas.vala
deleted file mode 100644
index 383b8e1de..000000000
--- a/src/Layouts/MainCanvas.vala
+++ /dev/null
@@ -1,211 +0,0 @@
-/*
-* Copyright (c) 2019-2020 Alecaddd (https://alecaddd.com)
-*
-* This file is part of Akira.
-*
-* Akira 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.
-
-* Akira 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 Akira. If not, see .
-*
-* Authored by: Alessandro "Alecaddd" Castellani
-* Authored by: Giacomo "giacomoalbe" Alberini
-*/
-
-public class Akira.Layouts.MainCanvas : Gtk.Grid {
- public const int CANVAS_SIZE = 100000;
- public const double SCROLL_DISTANCE = 0;
-
- public Gtk.ScrolledWindow main_scroll;
-
- public Akira.Lib.Canvas canvas;
-
- public weak Akira.Window window { get; construct; }
-
- private Gtk.Overlay main_overlay;
- private Granite.Widgets.OverlayBar overlaybar;
- private Granite.Widgets.Toast notification;
-
- private double scroll_origin_x = 0;
- private double scroll_origin_y = 0;
-
- public MainCanvas (Akira.Window window) {
- Object (window: window, orientation: Gtk.Orientation.VERTICAL);
- }
-
- construct {
- get_style_context ().add_class ("main-canvas");
-
- main_overlay = new Gtk.Overlay ();
- notification = new Granite.Widgets.Toast (_(""));
-
- main_scroll = new Gtk.ScrolledWindow (null, null);
- main_scroll.expand = true;
-
- // Overlay the scrollbars only if mouse pointer is inside canvas
- main_scroll.overlay_scrolling = false;
-
- // Change visibility of canvas scrollbars
- main_scroll.set_policy (Gtk.PolicyType.NEVER, Gtk.PolicyType.NEVER);
-
- canvas = new Akira.Lib.Canvas (window);
- canvas.set_bounds (0, 0, CANVAS_SIZE, CANVAS_SIZE);
- canvas.set_scale (1.0);
-
- canvas.canvas_moved.connect ((event_x, event_y) => {
- // Move scroll window according to normalized mouse delta
- // relative to the scroll window, so with Canvas' pixel
- // coordinates translated into ScrolledWindow's one.
- double event_x_pixel_space = event_x;
- double event_y_pixel_space = event_y;
-
- // Convert coordinates to pixel space, which does account for
- // canvas scale and canvas translation.
- // Otherwise, delta can start to "diverge" due to the
- // translation of starting point happening during canvas translation
- canvas.convert_to_pixels (ref event_x_pixel_space, ref event_y_pixel_space);
-
- var delta_x = event_x_pixel_space - scroll_origin_x;
- var delta_y = event_y_pixel_space - scroll_origin_y;
-
- main_scroll.hadjustment.value -= delta_x;
- main_scroll.vadjustment.value -= delta_y;
- });
-
- canvas.canvas_scroll_set_origin.connect ((origin_x, origin_y) => {
- // Update scroll origin on Canvas' button_press_event
- scroll_origin_x = origin_x;
- scroll_origin_y = origin_y;
-
- canvas.convert_to_pixels (ref scroll_origin_x, ref scroll_origin_y);
- });
-
- canvas.scroll_event.connect (on_scroll);
-
- main_scroll.add (canvas);
-
- main_overlay.add (main_scroll);
- main_overlay.add_overlay (notification);
-
- add (main_overlay);
-
- // Set up event listeners.
- window.event_bus.exporting.connect (on_exporting);
- window.event_bus.export_completed.connect (on_export_completed);
- window.event_bus.canvas_notification.connect (trigger_notification);
- }
-
- public bool on_scroll (Gdk.EventScroll event) {
- bool is_shift = (event.state & Gdk.ModifierType.SHIFT_MASK) > 0;
- bool is_ctrl = (event.state & Gdk.ModifierType.CONTROL_MASK) > 0;
-
- double delta_x, delta_y;
- event.get_scroll_deltas (out delta_x, out delta_y);
-
- if (delta_y < -SCROLL_DISTANCE) {
- // Scroll UP.
- if (is_ctrl) {
- // Divide the delta if it's too high. This fixes the zoom with
- // the mouse wheel.
- if (delta_y <= -1) {
- delta_y /= 10;
- }
- // Get the current zoom before zooming.
- double old_zoom = canvas.get_scale ();
- // Zoom in.
- window.event_bus.adjust_zoom (delta_y * -1, false, null);
- // Adjust zoom based on cursor position.
- zoom_on_cursor (event, old_zoom);
- } else if (is_shift) {
- main_scroll.hadjustment.value += delta_y * 10;
- } else {
- main_scroll.vadjustment.value += delta_y * 10;
- }
- } else if (delta_y > SCROLL_DISTANCE) {
- // Scroll DOWN.
- if (is_ctrl) {
- // Divide the delta if it's too high. This fixes the zoom with
- // the mouse wheel.
- if (delta_y >= 1) {
- delta_y /= 10;
- }
- // Get the current zoom before zooming.
- double old_zoom = canvas.get_scale ();
- // Zoom out.
- window.event_bus.adjust_zoom (-delta_y, false, null);
- // Adjust zoom based on cursor position.
- zoom_on_cursor (event, old_zoom);
- } else if (is_shift) {
- main_scroll.hadjustment.value += delta_y * 10;
- } else {
- main_scroll.vadjustment.value += delta_y * 10;
- }
- }
-
- if (delta_x < -SCROLL_DISTANCE) {
- main_scroll.hadjustment.value += delta_x * 10;
- } else if (delta_x > SCROLL_DISTANCE) {
- main_scroll.hadjustment.value += delta_x * 10;
- }
-
- return true;
- }
-
- private void zoom_on_cursor (Gdk.EventScroll event, double old_zoom) {
- // The regular zoom mode shifts the visible viewing area
- // to center itself (it already has one translation applied)
- // so you cannot just move the viewing area by the distance
- // of the current mouse location and the new mouse location.
-
- // If you want to zoom to your mouse you need to find the
- // difference between the distances of the current mouse location
- // in the current view scale to the left view border and the new
- // mouse location that has the new canvas scale applied to the
- // new left view border and shift the view by that difference.
- int width = main_scroll.get_allocated_width ();
- int height = main_scroll.get_allocated_height ();
-
- var center_x = main_scroll.hadjustment.value + (width / 2);
- var center_y = main_scroll.vadjustment.value + (height / 2);
-
- var old_center_x = (center_x / canvas.get_scale ()) * old_zoom;
- var old_center_y = (center_y / canvas.get_scale ()) * old_zoom;
-
- var new_event_x = (event.x / old_zoom) * canvas.get_scale ();
- var new_event_y = (event.y / old_zoom) * canvas.get_scale ();
-
- var old_hadjustment = old_center_x - (width / 2);
- var old_vadjustment = old_center_y - (height / 2);
-
- main_scroll.hadjustment.value +=
- (new_event_x - main_scroll.hadjustment.value) - (event.x - old_hadjustment);
- main_scroll.vadjustment.value +=
- (new_event_y - main_scroll.vadjustment.value) - (event.y - old_vadjustment);
- }
-
- private async void on_exporting (string message) {
- overlaybar = new Granite.Widgets.OverlayBar (main_overlay);
- overlaybar.label = message;
- overlaybar.active = true;
- show_all ();
- }
-
- private async void on_export_completed () {
- main_overlay.remove (overlaybar);
- overlaybar = null;
- yield trigger_notification (_("Export completed!"));
- }
-
- private async void trigger_notification (string message) {
- notification.title = message;
- notification.send_notification ();
- }
-}
diff --git a/src/Layouts/MainViewCanvas.vala b/src/Layouts/MainViewCanvas.vala
deleted file mode 100644
index 1f4b8feff..000000000
--- a/src/Layouts/MainViewCanvas.vala
+++ /dev/null
@@ -1,129 +0,0 @@
-/*
-* Copyright (c) 2019-2020 Alecaddd (https://alecaddd.com)
-*
-* This file is part of Akira.
-*
-* Akira 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.
-
-* Akira 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 Akira. If not, see .
-*
-* Authored by: Alessandro "Alecaddd" Castellani
-* Authored by: Giacomo "giacomoalbe" Alberini
-*/
-
-public class Akira.Layouts.MainViewCanvas : Gtk.Grid {
- public const int CANVAS_SIZE = 100000;
- public const double SCROLL_DISTANCE = 0;
-
- public Gtk.ScrolledWindow main_scroll;
-
- public Akira.Lib.ViewCanvas canvas;
-
- public weak Akira.Window window { get; construct; }
-
- private Gtk.Overlay main_overlay;
- private Granite.Widgets.Toast notification;
-
- private double scroll_origin_x = 0;
- private double scroll_origin_y = 0;
-
- public MainViewCanvas (Akira.Window window) {
- Object (window: window, orientation: Gtk.Orientation.VERTICAL);
- }
-
- construct {
- get_style_context ().add_class ("main-canvas");
-
- main_overlay = new Gtk.Overlay ();
- notification = new Granite.Widgets.Toast ("");
-
- main_scroll = new Gtk.ScrolledWindow (null, null);
- main_scroll.expand = true;
-
- // Overlay the scrollbars only if mouse pointer is inside canvas
- main_scroll.overlay_scrolling = false;
-
- // Change visibility of canvas scrollbars
- main_scroll.set_policy (Gtk.PolicyType.NEVER, Gtk.PolicyType.NEVER);
-
- canvas = new Akira.Lib.ViewCanvas (window);
- canvas.set_bounds (Geometry.Rectangle.with_coordinates (0, 0, CANVAS_SIZE, CANVAS_SIZE));
- canvas.scale = 1.0;
-
- canvas.canvas_moved.connect ((event_x, event_y) => {
- // Move scroll window according to normalized mouse delta
- // relative to the scroll window, so with Canvas' pixel
- // coordinates translated into ScrolledWindow's one.
- double event_x_pixel_space = event_x;
- double event_y_pixel_space = event_y;
-
- // Convert coordinates to pixel space, which does account for
- // canvas scale and canvas translation.
- // Otherwise, delta can start to "diverge" due to the
- // translation of starting point happening during canvas translation
- canvas.convert_to_pixels (ref event_x_pixel_space, ref event_y_pixel_space);
-
- var delta_x = event_x_pixel_space - scroll_origin_x;
- var delta_y = event_y_pixel_space - scroll_origin_y;
-
- main_scroll.hadjustment.value -= delta_x;
- main_scroll.vadjustment.value -= delta_y;
- });
-
- canvas.canvas_scroll_set_origin.connect ((origin_x, origin_y) => {
- // Update scroll origin on Canvas' button_press_event
- scroll_origin_x = origin_x;
- scroll_origin_y = origin_y;
-
- canvas.convert_to_pixels (ref scroll_origin_x, ref scroll_origin_y);
- });
-
- canvas.scroll_event.connect (on_scroll);
-
- main_scroll.add (canvas);
-
- main_overlay.add (main_scroll);
- main_overlay.add_overlay (notification);
-
- add (main_overlay);
- }
-
- public bool on_scroll (Gdk.EventScroll event) {
- double delta_x, delta_y;
- event.get_scroll_deltas (out delta_x, out delta_y);
-
- if (canvas.ctrl_is_pressed) {
- var norm_scale = canvas.scale / Lib.ViewCanvas.MAX_SCALE;
- delta_y *= 1 - (1 - norm_scale) * (1 - norm_scale);
- window.event_bus.adjust_zoom (-delta_y, false, Geometry.Point (event.x, event.y));
- return true;
- }
-
- if (canvas.shift_is_pressed) {
- main_scroll.hadjustment.value += delta_y * 10;
- return true;
- }
-
- main_scroll.hadjustment.value += delta_x * 10;
- main_scroll.vadjustment.value += delta_y * 10;
- return true;
- }
-
- /**
- * Pass a simple string message and trigger the Granite.Toast notification
- * At the top of the Canvas.
- */
- public void trigger_notification (string message) {
- notification.title = message;
- notification.send_notification ();
- }
-}
diff --git a/src/Layouts/MainWindow.vala b/src/Layouts/MainWindow.vala
deleted file mode 100644
index a4ea93e20..000000000
--- a/src/Layouts/MainWindow.vala
+++ /dev/null
@@ -1,103 +0,0 @@
-/*
-* Copyright (c) 2019 Alecaddd (http://alecaddd.com)
-*
-* This file is part of Akira.
-*
-* Akira 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.
-
-* Akira 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 Akira. If not, see .
-*
-* Authored by: Alessandro "Alecaddd" Castellani
-*/
-
-public class Akira.Layouts.MainWindow : Gtk.Grid {
- public weak Akira.Window window { get; construct; }
-
- public Akira.Layouts.MainViewCanvas main_view_canvas;
-
- private Layouts.Sidebars.LayersSidebar layers_sidebar;
- private Layouts.Sidebars.OptionsSidebar options_sidebar;
-
- public Gtk.Paned pane;
- public Gtk.Paned pane2;
-
- public MainWindow (Akira.Window window) {
- Object (window: window);
- }
-
- construct {
- main_view_canvas = new Layouts.MainViewCanvas (window);
- layers_sidebar = new Layouts.Sidebars.LayersSidebar (main_view_canvas.canvas);
- options_sidebar = new Layouts.Sidebars.OptionsSidebar (main_view_canvas.canvas);
-
- pane = new Gtk.Paned (Gtk.Orientation.HORIZONTAL);
- pane2 = new Gtk.Paned (Gtk.Orientation.HORIZONTAL);
- pane.pack2 (pane2, true, false);
- pane2.pack1 (main_view_canvas, true, true);
-
- if (!settings.get_boolean ("invert-sidebar")) {
- pane.pack1 (options_sidebar, false, false);
- pane2.pack2 (layers_sidebar, false, false);
- } else {
- pane.pack1 (layers_sidebar, false, false);
- pane2.pack2 (options_sidebar, false, false);
- }
-
- attach (pane, 0, 0, 1, 1);
- }
-
- public void focus_canvas () {
- main_view_canvas.canvas.focus_canvas ();
- }
-
- /*
- * Force the layers panel to show all its newly added children, only after
- * all items have actually been created.
- */
- public void show_added_layers (int added) {
- layers_sidebar.layers_listbox.show_added_layers (added);
- }
-
- /*
- * Pass the list of nodes ids to be removed from the layers list.
- */
- public void remove_layers (GLib.Array ids) {
- layers_sidebar.layers_listbox.remove_items (ids);
- }
-
- /*
- * Pass the list of nodes ids to be added to the layers list.
- */
- public void add_layers (GLib.Array ids) {
- layers_sidebar.layers_listbox.add_items (ids);
- }
-
- public void set_children_locked (int[] nodes, bool is_locked) {
- layers_sidebar.layers_listbox.set_children_locked (nodes, is_locked);
- }
-
- /*
- * Regenerate the entire layers list. This is used during history navigation.
- */
- public void regenerate_list (bool go_to_layer = false) {
- layers_sidebar.layers_listbox.clear_list ();
- layers_sidebar.layers_listbox.regenerate_list (go_to_layer);
- }
-
- public void refresh_fills () {
- options_sidebar.fills_panel.fills_listbox.refresh_list ();
- }
-
- public void refresh_borders () {
- options_sidebar.borders_panel.borders_listbox.refresh_list ();
- }
-}
diff --git a/src/Layouts/Partials/BlendingModeItem.vala b/src/Layouts/Partials/BlendingModeItem.vala
deleted file mode 100644
index 490d3990e..000000000
--- a/src/Layouts/Partials/BlendingModeItem.vala
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
-* Copyright (c) 2019 Alecaddd (http://alecaddd.com)
-*
-* This file is part of Akira.
-*
-* Akira 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.
-
-* Akira 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 Akira. If not, see .
-*
-* Authored by: Giacomo "giacomoalbe" Alberini
-*/
-
-public class Akira.Layouts.Partials.BlendingModeItem : Gtk.Label {
- public Akira.Utils.BlendingMode mode { get; construct; }
-
- public BlendingModeItem (Akira.Utils.BlendingMode mode) {
- Object (
- mode: mode
- );
- }
-
- construct {
- label = mode.get_name ();
- halign = Gtk.Align.START;
-
- get_style_context ().add_class (Gtk.STYLE_CLASS_MENUITEM);
- }
-}
diff --git a/src/Layouts/Partials/BorderItem.vala b/src/Layouts/Partials/BorderItem.vala
deleted file mode 100644
index fdac3924a..000000000
--- a/src/Layouts/Partials/BorderItem.vala
+++ /dev/null
@@ -1,121 +0,0 @@
-/**
- * Copyright (c) 2019-2021 Alecaddd (https://alecaddd.com)
- *
- * This file is part of Akira.
- *
- * Akira 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.
-
- * Akira 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 Akira. If not, see .
- *
- * Authored by: Alessandro "alecaddd" Castellani
- * Authored by: Ivan "isneezy" Vilanculo
- */
-
-public class Akira.Layouts.Partials.BorderItem : Gtk.Grid {
- private unowned Akira.Window window;
- private unowned Lib.Components.Border border;
-
- private Gtk.Button hidden_button;
- private Gtk.Button delete_button;
- private Gtk.Image hidden_button_icon;
-
- private bool hidden {
- owned get {
- return border.hidden;
- } set {
- border.hidden = value;
- set_hidden_button ();
- toggle_ui_visibility ();
- }
- }
-
- public signal void border_deleted ();
-
- public BorderItem (Akira.Window window, Lib.Components.Border border) {
- this.window = window;
- this.border = border;
-
- create_ui ();
- hidden = border.hidden;
-
- create_event_bindings ();
- show_all ();
- }
-
- private void create_ui () {
- margin_top = margin_bottom = 5;
-
- var fill_chooser = new Gtk.Grid ();
- fill_chooser.hexpand = true;
- fill_chooser.margin_end = 5;
-
- fill_chooser.add (new Widgets.ColorRow (window, new Models.ColorModel (null, border)));
-
- hidden_button = new Gtk.Button ();
- hidden_button.get_style_context ().add_class (Gtk.STYLE_CLASS_FLAT);
- hidden_button.get_style_context ().add_class ("button-rounded");
- hidden_button.can_focus = false;
- hidden_button.valign = Gtk.Align.CENTER;
-
- delete_button = new Gtk.Button ();
- delete_button.get_style_context ().add_class (Gtk.STYLE_CLASS_FLAT);
- delete_button.get_style_context ().add_class ("button-rounded");
- delete_button.can_focus = false;
- delete_button.valign = Gtk.Align.CENTER;
- delete_button.set_tooltip_text (_("Remove border color"));
- delete_button.add (new Gtk.Image.from_icon_name ("user-trash-symbolic",
- Gtk.IconSize.SMALL_TOOLBAR));
-
- attach (fill_chooser, 0, 0, 1, 1);
- attach (hidden_button, 1, 0, 1, 1);
- attach (delete_button, 2, 0, 1, 1);
- }
-
- private void create_event_bindings () {
- delete_button.clicked.connect (on_delete_item);
- hidden_button.clicked.connect (toggle_visibility);
- }
-
- private void on_delete_item () {
- border.remove ();
- border_deleted ();
- }
-
- private void set_hidden_button () {
- if (hidden_button_icon != null) {
- hidden_button.remove (hidden_button_icon);
- }
-
- hidden_button_icon = new Gtk.Image.from_icon_name (
- "layer-%s-symbolic".printf (hidden ? "hidden" : "visible"),
- Gtk.IconSize.SMALL_TOOLBAR);
-
- hidden_button.add (hidden_button_icon);
- hidden_button_icon.show_all ();
- }
-
- private void toggle_visibility () {
- hidden = !hidden;
- toggle_ui_visibility ();
- }
-
- private void toggle_ui_visibility () {
- if (hidden) {
- get_style_context ().add_class ("disabled");
- hidden_button.set_tooltip_text (_("Show border"));
- return;
- }
-
- hidden_button.set_tooltip_text (_("Hide border"));
- get_style_context ().remove_class ("disabled");
- }
-}
diff --git a/src/Layouts/Partials/BorderRadiusPanel.vala b/src/Layouts/Partials/BorderRadiusPanel.vala
deleted file mode 100644
index 6e55bc76a..000000000
--- a/src/Layouts/Partials/BorderRadiusPanel.vala
+++ /dev/null
@@ -1,362 +0,0 @@
-/*
-* Copyright (c) 2019 Alecaddd (https://alecaddd.com)
-*
-* This file is part of Akira.
-*
-* Akira 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.
-
-* Akira 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 Akira. If not, see .
-*
-* Authored by: Bilal Elmoussaoui
-* Authored by: Alessandro "Alecaddd" Castellani
-*/
-
-public class Akira.Layouts.Partials.BorderRadiusPanel : Gtk.Grid {
- public weak Akira.Window window { get; construct; }
-
- public Gtk.Label label;
- private Gtk.Revealer options_revealer;
- private Gtk.Grid options_grid;
- private Gtk.Adjustment radius_adj;
- private Gtk.Scale border_radius_scale;
- private Widgets.InputField border_radius_entry;
- private Gtk.ToggleButton options_button;
-
- private Widgets.InputField border_radius_bottom_left_entry;
- private Widgets.InputField border_radius_bottom_right_entry;
- private Widgets.InputField border_radius_top_left_entry;
- private Widgets.InputField border_radius_top_right_entry;
-
- private Gtk.Switch autoscale_switch;
- private Gtk.Switch uniform_switch;
- private Binding radius_binding;
- private Binding uniform_binding;
- private Binding autoscale_binding;
- private double max_value;
-
- private Akira.Lib.Items.CanvasRect _selected_item;
- private Akira.Lib.Items.CanvasRect selected_item {
- get {
- return _selected_item;
- } set {
- // If the same item is already selected, or the value is still null
- // we don't do anything to prevent redraw and calculations.
- if (_selected_item == value) {
- return;
- }
- disconnect_previous_item ();
- _selected_item = value;
- if (_selected_item == null || _selected_item.border_radius == null) {
- disable ();
- return;
- }
- enable ();
- }
- }
-
- public bool toggled {
- get {
- return visible;
- } set {
- visible = value;
- no_show_all = !value;
- }
- }
-
- public BorderRadiusPanel (Akira.Window window) {
- Object (
- window: window,
- orientation: Gtk.Orientation.VERTICAL
- );
- }
-
- construct {
- var title_cont = new Gtk.Grid ();
- title_cont.get_style_context ().add_class ("option-panel");
-
- label = new Gtk.Label (_("Style"));
- label.halign = Gtk.Align.FILL;
- label.xalign = 0;
- label.hexpand = true;
- label.set_ellipsize (Pango.EllipsizeMode.END);
- title_cont.attach (label, 0, 0, 1, 1);
-
- attach (title_cont, 0, 0, 1, 1);
-
- var panel_grid = new Gtk.Grid ();
- get_style_context ().add_class ("style-panel");
- panel_grid.row_spacing = 6;
- panel_grid.border_width = 12;
- panel_grid.column_spacing = 6;
- panel_grid.hexpand = true;
- attach (panel_grid, 0, 1, 1, 1);
-
- var border_radius_label = new Gtk.Label (_("Border Radius"));
- border_radius_label.get_style_context ().add_class ("group-title");
- border_radius_label.halign = Gtk.Align.START;
- border_radius_label.hexpand = true;
- border_radius_label.margin_bottom = 2;
- panel_grid.attach (border_radius_label, 0, 1, 3, 1);
-
- radius_adj = new Gtk.Adjustment (0, 0, 1.0, 10.0, 0, 0);
- border_radius_scale = new Gtk.Scale (Gtk.Orientation.HORIZONTAL, radius_adj);
- border_radius_scale.digits = 0;
- border_radius_scale.draw_value = false;
- border_radius_scale.valign = Gtk.Align.CENTER;
- border_radius_scale.halign = Gtk.Align.FILL;
- border_radius_scale.hexpand = true;
- panel_grid.attach (border_radius_scale, 0, 2, 1, 1);
-
- border_radius_entry = new Widgets.InputField (
- Widgets.InputField.Unit.PIXEL, 7, true, true);
- border_radius_entry.entry.hexpand = false;
- border_radius_entry.entry.width_request = 64;
- border_radius_entry.valign = Gtk.Align.CENTER;
- panel_grid.attach (border_radius_entry, 1, 2, 1, 1);
-
- border_radius_entry.entry.bind_property (
- "value", radius_adj, "value",
- BindingFlags.BIDIRECTIONAL | BindingFlags.SYNC_CREATE);
-
- var options_image = new Gtk.Image.from_icon_name ("open-menu-symbolic", Gtk.IconSize.BUTTON);
- options_button = new Gtk.ToggleButton ();
- options_button.valign = Gtk.Align.CENTER;
- options_button.halign = Gtk.Align.END;
- options_button.get_style_context ().add_class (Gtk.STYLE_CLASS_FLAT);
- options_button.add (options_image);
- options_button.can_focus = false;
- options_button.set_tooltip_text (_("Border radius options"));
- panel_grid.attach (options_button, 2, 2, 1, 1);
-
- options_revealer = new Gtk.Revealer ();
- options_revealer.transition_type = Gtk.RevealerTransitionType.NONE;
- panel_grid.attach (options_revealer, 0, 3, 3, 1);
-
- options_grid = new Gtk.Grid ();
- options_grid.border_width = 12;
- options_grid.hexpand = true;
-
- var border_entries_grid = new Gtk.Grid ();
- border_entries_grid.row_spacing = 12;
- border_entries_grid.border_width = 12;
- border_entries_grid.column_spacing = 12;
- border_entries_grid.hexpand = true;
-
- border_radius_top_left_entry = new Widgets.InputField (
- Widgets.InputField.Unit.PIXEL, 7, true, true);
- border_radius_top_left_entry.entry.hexpand = false;
- border_radius_top_left_entry.entry.width_request = 64;
- border_radius_top_left_entry.valign = Gtk.Align.CENTER;
- border_radius_top_left_entry.halign = Gtk.Align.START;
- border_entries_grid.attach (border_radius_top_left_entry, 0, 0, 1, 1);
-
- border_radius_top_right_entry = new Widgets.InputField (
- Widgets.InputField.Unit.PIXEL, 7, true, true);
- border_radius_top_right_entry.entry.hexpand = false;
- border_radius_top_right_entry.entry.width_request = 64;
- border_radius_top_right_entry.valign = Gtk.Align.CENTER;
- border_radius_top_right_entry.halign = Gtk.Align.END;
- border_entries_grid.attach (border_radius_top_right_entry, 1, 0, 1, 1);
-
- border_radius_bottom_left_entry = new Widgets.InputField (
- Widgets.InputField.Unit.PIXEL, 7, true, true);
- border_radius_bottom_left_entry.entry.hexpand = false;
- border_radius_bottom_left_entry.entry.width_request = 64;
- border_radius_bottom_left_entry.valign = Gtk.Align.CENTER;
- border_radius_bottom_left_entry.halign = Gtk.Align.START;
- border_entries_grid.attach (border_radius_bottom_left_entry, 0, 1, 1, 1);
-
- border_radius_bottom_right_entry = new Widgets.InputField (
- Widgets.InputField.Unit.PIXEL, 7, true, true);
- border_radius_bottom_right_entry.entry.hexpand = false;
- border_radius_bottom_right_entry.entry.width_request = 64;
- border_radius_bottom_right_entry.valign = Gtk.Align.CENTER;
- border_radius_bottom_right_entry.halign = Gtk.Align.END;
- border_entries_grid.attach (border_radius_bottom_right_entry, 1, 1, 1, 1);
-
- options_grid.attach (border_entries_grid, 0, 0, 1, 1);
- options_revealer.add (options_grid);
-
- var border_options_grid = new Gtk.Grid ();
- border_options_grid.row_spacing = 6;
- border_options_grid.border_width = 12;
- border_options_grid.column_spacing = 6;
- border_options_grid.hexpand = true;
-
- autoscale_switch = new Gtk.Switch ();
- autoscale_switch.valign = Gtk.Align.CENTER;
- autoscale_switch.halign = Gtk.Align.START;
- border_options_grid.attach (autoscale_switch, 0, 0, 1, 1);
- var autoscale_label = new Gtk.Label (_("Autoscale Corners"));
- autoscale_label.valign = Gtk.Align.CENTER;
- autoscale_label.halign = Gtk.Align.START;
- border_options_grid.attach (autoscale_label, 1, 0, 1, 1);
-
- uniform_switch = new Gtk.Switch ();
- uniform_switch.valign = Gtk.Align.CENTER;
- uniform_switch.halign = Gtk.Align.START;
- border_options_grid.attach (uniform_switch, 0, 1, 1, 1);
- var uniform_label = new Gtk.Label (_("Uniform Corners"));
- uniform_label.valign = Gtk.Align.CENTER;
- uniform_label.halign = Gtk.Align.START;
- border_options_grid.attach (uniform_label, 1, 1, 1, 1);
- options_grid.attach (border_options_grid, 0, 1, 1, 1);
- show_all ();
-
- bind_signals ();
- }
-
- private void bind_signals () {
- toggled = false;
- window.event_bus.selected_items_list_changed.connect (on_selected_items_list_changed);
- options_button.toggled.connect (() => {
- options_revealer.reveal_child = !options_revealer.child_revealed;
- window.event_bus.request_widget_redraw ();
- });
-
- uniform_switch.notify["active"].connect (() => {
- update_all_borders (uniform_switch.active);
- });
-
- // border_radius_top_left_entry.entry.changed.connect (on_radius_change);
- // border_radius_top_right_entry.entry.changed.connect (on_radius_change);
- // border_radius_bottom_right_entry.entry.changed.connect (on_radius_change);
- // border_radius_bottom_left_entry.entry.changed.connect (on_radius_change);
- }
-
- private void on_selected_items_list_changed (List selected_items) {
- // Interrupt if we don't have an item selected or if more than 1 is selected
- // since we can't handle the border radius of multiple items at once.
- if (selected_items.length () == 0 || selected_items.length () > 1) {
- selected_item = null;
- toggled = false;
- return;
- }
-
- if (!(selected_items.nth_data (0) is Akira.Lib.Items.CanvasRect)) {
- selected_item = null;
- toggled = false;
- return;
- }
-
- if (selected_item == null || selected_item != selected_items.nth_data (0)) {
- toggled = true;
- selected_item = (Akira.Lib.Items.CanvasRect) selected_items.nth_data (0);
- }
- }
-
- private void on_size_change () {
- var max_size = double.min (selected_item.width, selected_item.height);
- max_value = Math.round (max_size / 2);
- radius_adj.upper = max_value;
- border_radius_entry.set_range (0, max_value);
-
- if (!selected_item.border_radius.autoscale) {
- return;
- }
-
- // Calculate the radius percentage and update the value on shape resize.
- var percentage = Math.round (border_radius_scale.get_value () / max_size * 100);
- border_radius_scale.set_value (Math.round (percentage * max_size / 100));
- }
-
- private void enable () {
- on_size_change ();
-
- uniform_switch.active = selected_item.border_radius.uniform;
- autoscale_switch.active = selected_item.border_radius.autoscale;
-
- // Uniform radius
- if (selected_item.border_radius.uniform) {
- radius_adj.value = selected_item.border_radius.x;
- }
- update_all_borders (selected_item.border_radius.uniform);
-
- // Non-Uniform radius
- // if (!selected_item.border_radius.uniform) {
- // border_radius_top_left_entry.entry.text = selected_item.radius_tl;
- // border_radius_top_right_entry.entry.text = selected_item.radius_tr;
- // border_radius_bottom_right_entry.entry.text = selected_item.radius_br;
- // border_radius_bottom_left_entry.entry.text = selected_item.radius_bl;
- // }
-
- radius_binding = radius_adj.bind_property (
- "value", selected_item.border_radius, "x",
- BindingFlags.SYNC_CREATE | BindingFlags.BIDIRECTIONAL);
-
- uniform_binding = uniform_switch.bind_property (
- "active", selected_item.border_radius, "uniform");
- autoscale_binding = autoscale_switch.bind_property (
- "active", selected_item.border_radius, "autoscale");
-
- selected_item.notify["width"].connect (on_size_change);
- selected_item.notify["height"].connect (on_size_change);
- }
-
- private void disconnect_previous_item () {
- // Disconnect the model binding if an item was previously stored.
- // This is necessary to prevent GObject Critical errors.
- if (selected_item != null) {
- selected_item.notify["width"].disconnect (on_size_change);
- selected_item.notify["height"].disconnect (on_size_change);
- }
- }
-
- private void update_all_borders (bool switch_active) {
- border_radius_scale.sensitive = switch_active;
- border_radius_entry.entry.sensitive = switch_active;
-
- border_radius_bottom_left_entry.entry.sensitive = !switch_active;
- border_radius_bottom_right_entry.entry.sensitive = !switch_active;
- border_radius_top_left_entry.entry.sensitive = !switch_active;
- border_radius_top_right_entry.entry.sensitive = !switch_active;
-
- string border_value = !switch_active ?
- ((int)border_radius_scale.get_value ()).to_string () :
- "";
- border_radius_bottom_left_entry.entry.text = border_value;
- border_radius_bottom_right_entry.entry.text = border_value;
- border_radius_top_left_entry.entry.text = border_value;
- border_radius_top_right_entry.entry.text = border_value;
- }
-
- private void disable () {
- // border_radius_top_left_entry.entry.changed.disconnect (on_radius_change);
- // border_radius_top_right_entry.entry.changed.disconnect (on_radius_change);
- // border_radius_bottom_right_entry.entry.changed.disconnect (on_radius_change);
- // border_radius_bottom_left_entry.entry.changed.disconnect (on_radius_change);
-
- radius_binding.unbind ();
- uniform_binding.unbind ();
- autoscale_binding.unbind ();
-
- autoscale_switch.active = false;
- uniform_switch.active = false;
-
- border_radius_scale.set_value (0);
-
- border_radius_entry.entry.text = "";
- border_radius_entry.entry.sensitive = false;
-
- border_radius_top_left_entry.entry.text = "";
- border_radius_top_left_entry.entry.sensitive = false;
-
- border_radius_top_right_entry.entry.text = "";
- border_radius_top_right_entry.entry.sensitive = false;
-
- border_radius_bottom_left_entry.entry.text = "";
- border_radius_bottom_left_entry.entry.sensitive = false;
-
- border_radius_bottom_right_entry.entry.text = "";
- border_radius_bottom_right_entry.entry.sensitive = false;
- }
-}
diff --git a/src/Layouts/Partials/BordersPanel.vala b/src/Layouts/Partials/BordersPanel.vala
deleted file mode 100644
index e193668b4..000000000
--- a/src/Layouts/Partials/BordersPanel.vala
+++ /dev/null
@@ -1,139 +0,0 @@
-/**
- * Copyright (c) 2019-2021 Alecaddd (https://alecaddd.com)
- *
- * This file is part of Akira.
- *
- * Akira 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.
-
- * Akira 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 Akira. If not, see .
- *
- * Authored by: Alessandro "alecaddd" Castellani
- */
-
-public class Akira.Layouts.Partials.BordersPanel : Gtk.Grid {
- private unowned Akira.Window window;
-
- public Gtk.Button add_btn;
- public Gtk.ListBox borders_list_container;
- private GLib.ListStore list;
- private unowned List? items;
-
- public bool toggled {
- get {
- return visible;
- } set {
- visible = value;
- no_show_all = !value;
- }
- }
-
- public BordersPanel (Akira.Window window) {
- this.window = window;
-
- var title_cont = new Gtk.Grid ();
- title_cont.orientation = Gtk.Orientation.HORIZONTAL;
- title_cont.hexpand = true;
- title_cont.get_style_context ().add_class ("option-panel");
-
- var label = new Gtk.Label (_("Borders"));
- label.halign = Gtk.Align.FILL;
- label.xalign = 0;
- label.hexpand = true;
- label.set_ellipsize (Pango.EllipsizeMode.END);
-
- add_btn = new Gtk.Button ();
- add_btn.get_style_context ().add_class (Gtk.STYLE_CLASS_FLAT);
- add_btn.can_focus = false;
- add_btn.valign = Gtk.Align.CENTER;
- add_btn.halign = Gtk.Align.CENTER;
- add_btn.set_tooltip_text (_("Add border"));
- add_btn.add (new Gtk.Image.from_icon_name ("list-add-symbolic", Gtk.IconSize.SMALL_TOOLBAR));
-
- title_cont.attach (label, 0, 0, 1, 1);
- title_cont.attach (add_btn, 1, 0, 1, 1);
-
- list = new GLib.ListStore (typeof (Lib.Components.Border));
-
- borders_list_container = new Gtk.ListBox ();
- borders_list_container.margin_top = 5;
- borders_list_container.margin_bottom = 15;
- borders_list_container.margin_start = 10;
- borders_list_container.margin_end = 5;
- borders_list_container.selection_mode = Gtk.SelectionMode.NONE;
- borders_list_container.get_style_context ().add_class ("fills-list");
-
- borders_list_container.bind_model (list, item => {
- var border_items = new Layouts.Partials.BorderItem (window, (Lib.Components.Border) item);
- border_items.border_deleted.connect (() => {
- reload_list (items);
- });
- return border_items;
- });
-
- attach (title_cont, 0, 0, 1, 1);
- attach (borders_list_container, 0, 1, 1, 1);
- show_all ();
-
- create_event_bindings ();
- }
-
- private void create_event_bindings () {
- toggled = false;
- window.event_bus.selected_items_list_changed.connect (reload_list);
-
- add_btn.clicked.connect (() => {
- var border_color = Gdk.RGBA ();
- border_color.parse (settings.border_color);
-
- foreach (Lib.Items.CanvasItem item in items) {
- list.insert (0, item.borders.add_border_color (border_color, (int) settings.border_size));
- }
- });
-
- // Listen to the model changes when adding/removing items.
- list.items_changed.connect ((position, removed, added) => {
- window.main_window.left_sidebar.queue_resize ();
- });
- }
-
- private void reload_list (List selected_items) {
- // Always clear the list model when a selection changes.
- list.remove_all ();
-
- if (selected_items.length () == 0) {
- items = null;
- toggled = false;
- return;
- }
-
- items = selected_items;
-
- bool show = false;
- foreach (Lib.Items.CanvasItem item in selected_items) {
- // Skip items that don't have a border item since there will be nothing to show.
- if (item.borders == null) {
- continue;
- }
-
- // At least an item has the borders component, so we can show the
- show = true;
-
- // Loops through all the available borders and add them tot he list model.
- // TODO: handle duplicate identical colors.
- foreach (Lib.Components.Border border in item.borders.borders) {
- list.insert (0, border);
- }
- }
-
- toggled = show;
- }
-}
diff --git a/src/Layouts/Partials/FillsPanel.vala b/src/Layouts/Partials/FillsPanel.vala
deleted file mode 100644
index f05344aea..000000000
--- a/src/Layouts/Partials/FillsPanel.vala
+++ /dev/null
@@ -1,140 +0,0 @@
-/**
- * Copyright (c) 2019-2021 Alecaddd (https://alecaddd.com)
- *
- * This file is part of Akira.
- *
- * Akira 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.
-
- * Akira 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 Akira. If not, see .
- *
- * Authored by: Giacomo "giacomoalbe" Alberini
- * Authored by: Alessandro "alecaddd" Castellani
- */
-
-public class Akira.Layouts.Partials.FillsPanel : Gtk.Grid {
- private unowned Akira.Window window;
-
- private Gtk.Button add_btn;
- private Gtk.ListBox fills_list_container;
- private GLib.ListStore list;
- private unowned List? items;
-
- public bool toggled {
- get {
- return visible;
- } set {
- visible = value;
- no_show_all = !value;
- }
- }
-
- public FillsPanel (Akira.Window window) {
- this.window = window;
-
- var title_cont = new Gtk.Grid ();
- title_cont.orientation = Gtk.Orientation.HORIZONTAL;
- title_cont.hexpand = true;
- title_cont.get_style_context ().add_class ("option-panel");
-
- var label = new Gtk.Label (_("Fills"));
- label.halign = Gtk.Align.FILL;
- label.xalign = 0;
- label.hexpand = true;
- label.set_ellipsize (Pango.EllipsizeMode.END);
-
- add_btn = new Gtk.Button ();
- add_btn.get_style_context ().add_class (Gtk.STYLE_CLASS_FLAT);
- add_btn.can_focus = false;
- add_btn.valign = Gtk.Align.CENTER;
- add_btn.halign = Gtk.Align.CENTER;
- add_btn.set_tooltip_text (_("Add fill color"));
- add_btn.add (new Gtk.Image.from_icon_name ("list-add-symbolic", Gtk.IconSize.SMALL_TOOLBAR));
-
- title_cont.attach (label, 0, 0, 1, 1);
- title_cont.attach (add_btn, 1, 0, 1, 1);
-
- list = new GLib.ListStore (typeof (Lib.Components.Fill));
-
- fills_list_container = new Gtk.ListBox ();
- fills_list_container.margin_top = 5;
- fills_list_container.margin_bottom = 15;
- fills_list_container.margin_start = 10;
- fills_list_container.margin_end = 5;
- fills_list_container.selection_mode = Gtk.SelectionMode.NONE;
- fills_list_container.get_style_context ().add_class ("fills-list");
-
- fills_list_container.bind_model (list, item => {
- var fill_item = new Layouts.Partials.FillItem (window, (Lib.Components.Fill) item);
- fill_item.fill_deleted.connect (() => {
- reload_list (items);
- });
- return fill_item;
- });
-
- attach (title_cont, 0, 0, 1, 1);
- attach (fills_list_container, 0, 1, 1, 1);
- show_all ();
-
- create_event_bindings ();
- }
-
- private void create_event_bindings () {
- toggled = false;
- window.event_bus.selected_items_list_changed.connect (reload_list);
-
- add_btn.clicked.connect (() => {
- var fill_color = Gdk.RGBA ();
- fill_color.parse (settings.fill_color);
-
- foreach (Lib.Items.CanvasItem item in items) {
- list.insert (0, item.fills.add_fill_color (fill_color));
- }
- });
-
- // Listen to the model changes when adding or removing items.
- list.items_changed.connect ((position, removed, added) => {
- window.main_window.left_sidebar.queue_resize ();
- });
- }
-
- private void reload_list (List selected_items) {
- // Always clear the list model when a selection changes.
- list.remove_all ();
-
- if (selected_items.length () == 0) {
- items = null;
- toggled = false;
- return;
- }
-
- items = selected_items;
-
- bool show = false;
- foreach (Lib.Items.CanvasItem item in selected_items) {
- // Skip items that don't have a fill item since there will be nothing to show.
- if (item.fills == null) {
- continue;
- }
-
- // At least an item has the fills component, so we can show the
- show = true;
-
- // Loops through all the available fills and add them tot he list model.
- // TODO: handle duplicate identical colors.
- foreach (Lib.Components.Fill fill in item.fills.fills) {
- list.insert (0, fill);
- }
- }
-
- toggled = show;
- }
-}
diff --git a/src/Layouts/Partials/PagesPanel.vala b/src/Layouts/Partials/PagesPanel.vala
deleted file mode 100644
index 488cff008..000000000
--- a/src/Layouts/Partials/PagesPanel.vala
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
-* Copyright (c) 2019 Alecaddd (http://alecaddd.com)
-*
-* This file is part of Akira.
-*
-* Akira 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.
-
-* Akira 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 Akira. If not, see .
-*
-* Authored by: Alessandro "Alecaddd" Castellani
-*/
-
-public class Akira.Layouts.Partials.PagesPanel : Gtk.ListBox {
- public weak Akira.Window window { get; construct; }
-
- // private bool scroll_up = false;
- // private bool scrolling = false;
- // private bool should_scroll = false;
- // public Gtk.Adjustment vadjustment;
-
- // private const int SCROLL_STEP_SIZE = 5;
- // private const int SCROLL_DISTANCE = 30;
- // private const int SCROLL_DELAY = 50;
-
- private const Gtk.TargetEntry TARGET_ENTRIES[] = {
- { "PAGES", Gtk.TargetFlags.SAME_APP, 0 }
- };
-
- public PagesPanel (Akira.Window window) {
- Object (
- window: window,
- activate_on_single_click: false,
- selection_mode: Gtk.SelectionMode.SINGLE
- );
- }
-
- construct {
- expand = true;
- }
-}
diff --git a/src/Layouts/Sidebars/LayersSidebar.vala b/src/Layouts/Sidebars/LayersSidebar.vala
deleted file mode 100644
index a35a9941d..000000000
--- a/src/Layouts/Sidebars/LayersSidebar.vala
+++ /dev/null
@@ -1,139 +0,0 @@
-/*
- * Copyright (c) 2021 Alecaddd (https://alecaddd.com)
- *
- * This file is part of Akira.
- *
- * Akira 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.
-
- * Akira 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 Akira. If not, see .
- *
- * Authored by: Alessandro "Alecaddd" Castellani
- */
-
-/*
- * Layout component containing the layers and pages containers.
- */
-public class Akira.Layouts.Sidebars.LayersSidebar : Gtk.Grid {
- public unowned Lib.ViewCanvas view_canvas { get; construct; }
-
- /*
- * Boolean attribute to show/hide the layers sidebar when requested for the
- * presentation mode option byt the user.
- */
- private bool toggled {
- get {
- return visible;
- }
- set {
- visible = value;
- no_show_all = !value;
-
- if (value) {
- layers_listbox.regenerate_list (true);
- } else {
- layers_listbox.clear_list ();
- }
- }
- }
-
- // Drag and Drop properties.
- private Gtk.Revealer motion_revealer;
- private Gtk.TargetList drop_targets;
- private const Gtk.TargetEntry TARGET_ENTRIES[] = {
- { "ARTBOARD", Gtk.TargetFlags.SAME_APP, 0 },
- { "LAYER", Gtk.TargetFlags.SAME_APP, 0 }
- };
-
- public Layouts.LayersList.LayerListBox layers_listbox;
- public Gtk.ScrolledWindow layers_scroll;
-
- public LayersSidebar (Lib.ViewCanvas canvas) {
- Object (
- view_canvas: canvas
- );
- }
-
- construct {
- get_style_context ().add_class ("sidebar-r");
- width_request = 220;
-
- drop_targets = new Gtk.TargetList (TARGET_ENTRIES);
-
- var pane = new Gtk.Paned (Gtk.Orientation.VERTICAL);
- pane.expand = true;
- pane.wide_handle = false;
- pane.position = 600;
-
- layers_listbox = new Layouts.LayersList.LayerListBox (view_canvas);
-
- layers_scroll = new Gtk.ScrolledWindow (null, null) {
- hscrollbar_policy = Gtk.PolicyType.NEVER,
- width_request = 158,
- expand = true
- };
- layers_scroll.add (layers_listbox);
-
- // Motion revealer for Drag and Drop on the top search bar.
- var motion_grid = new Gtk.Grid ();
- motion_grid.get_style_context ().add_class ("grid-motion");
- motion_grid.height_request = 2;
-
- motion_revealer = new Gtk.Revealer ();
- motion_revealer.transition_type = Gtk.RevealerTransitionType.SLIDE_DOWN;
- motion_revealer.add (motion_grid);
-
- var top_panel = new Gtk.Grid ();
- top_panel.attach (build_search_bar (), 0, 0, 1, 1);
- top_panel.attach (motion_revealer, 0, 1, 1, 1);
- top_panel.attach (layers_scroll, 0, 2, 1, 1);
-
- pane.pack1 (top_panel, false, false);
-
- attach (pane, 0 , 0 , 1, 1);
-
- // Connect signals.
- view_canvas.window.event_bus.toggle_presentation_mode.connect (toggle);
- }
-
- private Gtk.Grid build_search_bar () {
- var search = new Gtk.SearchEntry ();
- search.hexpand = true;
- search.margin = 5;
- search.placeholder_text = _("Search Layers");
-
- search.focus_in_event.connect (handle_focus_in);
- search.focus_out_event.connect (handle_focus_out);
-
- var search_grid = new Gtk.Grid ();
- search_grid.get_style_context ().add_class ("border-bottom");
- search_grid.add (search);
-
- return search_grid;
- }
-
- private bool handle_focus_in (Gdk.EventFocus event) {
- view_canvas.window.event_bus.disconnect_typing_accel ();
- return false;
- }
-
- private bool handle_focus_out (Gdk.EventFocus event) {
- view_canvas.window.event_bus.connect_typing_accel ();
- return false;
- }
-
- /*
- * Toggle the visibility of the entire panel.
- */
- private void toggle () {
- toggled = !toggled;
- }
-}
diff --git a/src/Layouts/Sidebars/OptionsSidebar.vala b/src/Layouts/Sidebars/OptionsSidebar.vala
deleted file mode 100644
index 182da60ca..000000000
--- a/src/Layouts/Sidebars/OptionsSidebar.vala
+++ /dev/null
@@ -1,72 +0,0 @@
-/*
-* Copyright (c) 2021 Alecaddd (http://alecaddd.com)
-*
-* This file is part of Akira.
-*
-* Akira 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.
-
-* Akira 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 Akira. If not, see .
-*
-* Authored by: Giacomo "giacomoalbe" Alberini
-*/
-
-public class Akira.Layouts.Sidebars.OptionsSidebar : Gtk.Grid {
- public unowned Lib.ViewCanvas view_canvas { get; construct; }
-
- public Layouts.FillsList.FillsPanel fills_panel;
- public Layouts.BordersList.BordersPanel borders_panel;
-
- public bool toggled {
- get {
- return visible;
- } set {
- visible = value;
- no_show_all = !value;
- }
- }
-
- public OptionsSidebar (Lib.ViewCanvas view_canvas) {
- Object (
- view_canvas: view_canvas
- );
- }
-
- construct {
- get_style_context ().add_class ("sidebar-l");
-
- // The alignment panel is the only widget that doesn't scroll.
- attach (new Layouts.Alignment.AlignmentPanel (view_canvas), 0, 0);
-
- var main_scroll = new Gtk.ScrolledWindow (null, null) {
- hscrollbar_policy = Gtk.PolicyType.NEVER,
- expand = true
- };
-
- fills_panel = new Layouts.FillsList.FillsPanel (view_canvas);
- borders_panel = new Layouts.BordersList.BordersPanel (view_canvas);
-
- var main_grid = new Gtk.Grid ();
- main_grid.attach (new Layouts.Transforms.TransformPanel (view_canvas), 0, 0);
- main_grid.attach (fills_panel, 0, 1);
- main_grid.attach (borders_panel, 0, 2);
-
- main_scroll.add (main_grid);
- attach (main_scroll, 0, 1);
-
- // Connect signals.
- view_canvas.window.event_bus.toggle_presentation_mode.connect (toggle);
- }
-
- private void toggle () {
- toggled = !toggled;
- }
-}
diff --git a/src/Layouts/Transforms/TransformPanel.vala b/src/Layouts/Transforms/TransformPanel.vala
deleted file mode 100644
index 8fd212419..000000000
--- a/src/Layouts/Transforms/TransformPanel.vala
+++ /dev/null
@@ -1,176 +0,0 @@
-/*
- * Copyright (c) 2022 Alecaddd (https://alecaddd.com)
- *
- * This file is part of Akira.
- *
- * Akira 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.
-
- * Akira 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 Akira. If not, see .
- *
- * Authored by: Alessandro "Alecaddd" Castellani
- */
-
-/*
- * Layout component containing the input fields representing the transformation
- * matrix of the selected items.
- */
-public class Akira.Layouts.Transforms.TransformPanel : Gtk.Grid {
- public unowned Lib.ViewCanvas view_canvas { get; construct; }
-
- public Widgets.LinkedInput x_input;
- public Widgets.LinkedInput y_input;
-
- public Widgets.LinkedInput width_input;
- public Widgets.LinkedInput height_input;
-
- public Widgets.LinkedInput rotation_input;
-
- public TransformPanel (Lib.ViewCanvas canvas) {
- Object (view_canvas: canvas);
-
- border_width = 12;
- row_spacing = column_spacing = 6;
- hexpand = true;
-
- var lock_image = new Gtk.Image.from_icon_name ("changes-allow-symbolic", Gtk.IconSize.BUTTON);
- var lock_button = new Gtk.ToggleButton () {
- tooltip_text = _("Lock Ratio"),
- image = lock_image,
- can_focus = false,
- sensitive = false
- };
- lock_button.get_style_context ().add_class (Gtk.STYLE_CLASS_FLAT);
- lock_button.get_style_context ().add_class ("label-colors");
-
- var hflip_button = new Gtk.ToggleButton () {
- hexpand = false,
- can_focus = false,
- sensitive = false,
- halign = valign = Gtk.Align.CENTER,
- tooltip_markup = Granite.markup_accel_tooltip ({"bracketleft"}, _("Flip Horizontally"))
- };
- hflip_button.get_style_context ().add_class (Gtk.STYLE_CLASS_FLAT);
- hflip_button.add (new Widgets.ButtonImage ("object-flip-horizontal"));
-
- var vflip_button = new Gtk.ToggleButton () {
- hexpand = false,
- can_focus = false,
- sensitive = false,
- halign = valign = Gtk.Align.CENTER,
- tooltip_markup = Granite.markup_accel_tooltip ({"bracketright"}, _("Flip Vertically"))
- };
- vflip_button.get_style_context ().add_class (Gtk.STYLE_CLASS_FLAT);
- vflip_button.add (new Widgets.ButtonImage ("object-flip-vertical"));
-
- var align_grid = new Gtk.Grid ();
- align_grid.hexpand = true;
- align_grid.column_homogeneous = true;
- align_grid.attach (hflip_button, 0, 0, 1, 1);
- align_grid.attach (vflip_button, 1, 0, 1, 1);
-
- var scale = new Gtk.Scale (
- Gtk.Orientation.HORIZONTAL,
- new Gtk.Adjustment (100.0, 0, 100.0, 0, 0, 0)
- ) {
- hexpand = true,
- sensitive = false,
- draw_value = false,
- digits = 0,
- margin_end = 20
- };
-
- var opacity_entry = new Widgets.InputField (
- view_canvas, Widgets.InputField.Unit.PERCENTAGE, 7, true, true);
- opacity_entry.entry.hexpand = false;
- opacity_entry.entry.width_request = 64;
-
- var opacity_grid = new Gtk.Grid ();
- opacity_grid.hexpand = true;
- opacity_grid.attach (scale, 0, 0, 1);
- opacity_grid.attach (opacity_entry, 1, 0, 1);
-
- attach (group_title (_("Position")), 0, 0, 3);
-
- x_input = new Widgets.LinkedInput (view_canvas, _("X"), _("Horizontal position"));
- attach (x_input, 0, 1, 1);
-
- y_input = new Widgets.LinkedInput (view_canvas, _("Y"), _("Vertical position"));
- attach (y_input, 2, 1, 1);
-
- attach (separator (), 0, 2, 3);
-
- attach (group_title (_("Size")), 0, 3, 3);
- width_input = new Widgets.LinkedInput (view_canvas, _("W"), _("Width"));
- attach (width_input, 0, 4, 1);
-
- attach (lock_button, 1, 4, 1);
-
- height_input = new Widgets.LinkedInput (view_canvas, _("H"), _("Height"));
- attach (height_input, 2, 4, 1);
-
- attach (separator (), 0, 5, 3);
-
- attach (group_title (_("Transform")), 0, 6, 3);
-
- rotation_input = new Widgets.LinkedInput (view_canvas, _("R"), _("Rotation degrees"), Widgets.InputField.Unit.DEGREES);
- attach (rotation_input, 0, 7, 1);
-
- attach (align_grid, 2, 7, 1);
- attach (separator (), 0, 8, 3);
- attach (group_title (_("Opacity")), 0, 9, 3);
- attach (opacity_grid, 0, 10, 3);
-
- view_canvas.window.event_bus.selection_geometry_modified.connect (on_selection_geometry_modified);
- }
-
- private Gtk.Label group_title (string title) {
- var title_label = new Gtk.Label (title) {
- halign = Gtk.Align.START,
- hexpand = true,
- margin_bottom = 2
- };
- title_label.get_style_context ().add_class ("group-title");
-
- return title_label;
- }
-
- private Gtk.Separator separator () {
- var sep = new Gtk.Separator (Gtk.Orientation.HORIZONTAL) {
- margin_bottom = 6
- };
- sep.get_style_context ().add_class ("panel-separator");
-
- return sep;
- }
-
- private void on_selection_geometry_modified () {
- unowned var sm = view_canvas.selection_manager;
- if (sm.selection == null || sm.selection.is_empty ()) {
- x_input.input_field.entry.set_value (0);
- y_input.input_field.entry.set_value (0);
- width_input.input_field.entry.set_value (0);
- height_input.input_field.entry.set_value (0);
- rotation_input.input_field.entry.set_value (0);
- return;
- }
-
- var quad = sm.selection.area (). quad ();
-
- x_input.input_field.entry.set_value (quad.tl_x);
- y_input.input_field.entry.set_value (quad.tl_y);
- width_input.input_field.entry.set_value (quad.width);
- height_input.input_field.entry.set_value (quad.height);
-
- double rot = Utils.GeometryMath.matrix_rotation_component (quad.transformation) * 180 / Math.PI;
- rotation_input.input_field.entry.set_value (rot);
- }
-}
diff --git a/src/Lib/Components/BorderRadius.vala b/src/Lib/Components/BorderRadius.vala
deleted file mode 100644
index 2b8dd246d..000000000
--- a/src/Lib/Components/BorderRadius.vala
+++ /dev/null
@@ -1,81 +0,0 @@
-/**
- * Copyright (c) 2019-2021 Alecaddd (https://alecaddd.com)
- *
- * This file is part of Akira.
- *
- * Akira 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.
-
- * Akira 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 Akira. If not, see .
- *
- * Authored by: Martin "mbfraga" Fraga
- */
-
-public class Akira.Lib.Components.BorderRadius : Component, Copyable {
- private int _x;
- private int _y;
- private bool _autoscale;
- private bool _uniform;
-
- public BorderRadius (int x, int y, bool autoscale, bool uniform) {
- _x = x;
- _y = y;
- _autoscale = autoscale;
- _uniform = uniform;
-
- if (_uniform) {
- _x = _y;
- }
- }
-
- public BorderRadius.deserialized (Json.Object obj) {
- _x = (int)obj.get_int_member ("x");
- _y = (int)obj.get_int_member ("y");
- _autoscale = obj.get_boolean_member ("autoscale");
- _uniform = obj.get_boolean_member ("uniform");
- }
-
- public override void serialize_details (ref Json.Object obj) {
- obj.set_int_member ("x", _x);
- obj.set_int_member ("y", _y);
- obj.set_boolean_member ("autoscale", _autoscale);
- obj.set_boolean_member ("uniform", _uniform);
- }
-
- public BorderRadius copy () {
- return new BorderRadius (_x, _y, _autoscale, _uniform);
- }
-
- // Recommended accessors
-
- public int x () { return _x; }
- public int y () { return _x; }
- public bool autoscale () { return _autoscale; }
- public bool uniform () { return _uniform; }
-
- // Mutators
-
- public BorderRadius with_x (int new_x) {
- return new BorderRadius (_x, _y, _autoscale, _uniform);
- }
-
- public BorderRadius with_y (int new_y) {
- return new BorderRadius (_x, new_y, _autoscale, _uniform);
- }
-
- public BorderRadius with_autoscale (bool new_autoscale) {
- return new BorderRadius (_x, _y, new_autoscale, _uniform);
- }
-
- public BorderRadius with_uniform (bool new_uniform) {
- return new BorderRadius (_x, _y, _autoscale, new_uniform);
- }
-}
diff --git a/src/Lib/Components/Borders.vala b/src/Lib/Components/Borders.vala
deleted file mode 100644
index 4e99e4b3a..000000000
--- a/src/Lib/Components/Borders.vala
+++ /dev/null
@@ -1,193 +0,0 @@
-/**
- * Copyright (c) 2019-2022 Alecaddd (https://alecaddd.com)
- *
- * This file is part of Akira.
- *
- * Akira 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.
-
- * Akira 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 Akira. If not, see .
- *
- * Authored by: Martin "mbfraga" Fraga
- */
-
-public class Akira.Lib.Components.Borders : Component, Copyable {
- public struct Border {
- public int _id;
- public Color _color;
- public double _size;
-
- public Border (int id = -1, Color color = Color (), double? size = null) {
- _id = id;
- _color = color;
- _size = size != null ? size : settings.border_size;
- }
-
- public Border.deserialized (int id, Json.Object obj) {
- _id = id;
- _color = Color.deserialized (obj.get_object_member ("color"));
- _size = (double)obj.get_int_member ("size");
- }
-
- public Json.Node serialize () {
- var obj = new Json.Object ();
- obj.set_int_member ("id", _id);
- obj.set_member ("color", _color.serialize ());
- obj.set_double_member ("size", _size);
- var node = new Json.Node (Json.NodeType.OBJECT);
- node.set_object (obj);
- return node;
- }
-
- // Recommended accessors.
- public int id {
- get {
- return _id;
- }
- }
- public Gdk.RGBA color {
- get {
- return _color.rgba;
- }
- }
- public bool hidden {
- get {
- return _color.hidden;
- }
- }
- public double size {
- get {
- return _size;
- }
- }
-
- // Mutators.
- public Border with_color (Color new_color) {
- return Border (_id, new_color, _size);
- }
-
- public Border with_size (double new_size) {
- return Border (_id, _color, new_size);
- }
- }
-
- public Border[] data;
-
- public Borders () {
- data = new Border[0];
- }
-
- public Borders.single_color (Color color, int size) {
- data = new Border[1];
- data[0] = Border (0, color, size);
- }
-
- public Borders.deserialized (Json.Object obj) {
- var arr = obj.get_array_member ("border_data").get_elements ();
- data = new Border[0];
-
- var idx = 0;
- foreach (unowned var border in arr) {
- data.resize (data.length + 1);
- data[idx] = Border.deserialized (idx, border.get_object ());
- ++idx;
- }
- }
-
- protected override void serialize_details (ref Json.Object obj) {
- var array = new Json.Array ();
-
- foreach (unowned var d in data) {
- array.add_element (d.serialize ());
- }
-
- var node = new Json.Node (Json.NodeType.ARRAY);
- node.set_array (array);
- obj.set_member ("border_data", node);
- }
-
- public Borders copy () {
- var cln = new Borders ();
- cln.data = data;
- return cln;
- }
-
- // Recommended accessors.
- public Border? border_from_id (int id) {
- foreach (unowned var border in data) {
- if (border.id == id) {
- return border.with_color (border._color);
- }
- }
- return null;
- }
-
- public bool replace (Border border) {
- for (var i = 0; i < data.length; ++i) {
- if (data[i].id == border.id) {
- data[i] = border;
- return true;
- }
- }
- return false;
- }
-
- /*
- * Create a new Border with the passed color and add it to the data structure.
- * It's up to the code requiring this to then replace the borders component.
- */
- public void append_border_with_color (Color color, double? size = null) {
- int latest_id = int.MIN;
- foreach (unowned var border in data) {
- latest_id = int.max (latest_id, border.id);
- }
- latest_id++;
- var border = Border ((int) latest_id, color, size);
- data.resize (data.length + 1);
- data[data.length - 1] = border;
- }
-
- public int remove (uint id) {
- var ct = 0;
- foreach (unowned var border in data) {
- if (border.id == id) {
- return remove_at (ct) ? 1 : -1;
- }
- ++ct;
- }
- return -1;
- }
-
- private bool remove_at (int pos) {
- if (pos >= data.length || pos < 0) {
- assert (false);
- return false;
- }
-
- data.move (pos + 1, pos, data.length - pos - 1);
- data.resize (data.length - 1);
- return true;
- }
-
- /*
- * Helper method used to retrieve the size of the thickest visible border.
- */
- public double get_border_width () {
- double size = 0;
- foreach (unowned var border in data) {
- if (border.hidden) {
- continue;
- }
- size = double.max (size, border.size);
- }
- return size;
- }
-}
diff --git a/src/Lib/Components/Color.vala b/src/Lib/Components/Color.vala
deleted file mode 100644
index 2205c055d..000000000
--- a/src/Lib/Components/Color.vala
+++ /dev/null
@@ -1,60 +0,0 @@
-/**
- * Copyright (c) 2019-2021 Alecaddd (https://alecaddd.com)
- *
- * This file is part of Akira.
- *
- * Akira 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.
-
- * Akira 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 Akira. If not, see .
- *
- * Authored by: Martin "mbfraga" Fraga
- */
-
-public struct Akira.Lib.Components.Color {
- public Gdk.RGBA rgba;
- public bool hidden;
-
- public Color (double r = 0.0, double g = 0.0, double b = 0.0, double a = 1.0, bool hidden = false) {
- rgba = Gdk.RGBA () { red = r, green = g, blue = b, alpha = a };
- }
-
- public Color.from_rgba (Gdk.RGBA rgba, bool hidden = false) {
- this.rgba = rgba;
- this.hidden = hidden;
- }
-
- public Color.deserialized (Json.Object obj) {
- var r = obj.get_double_member ("r");
- var g = obj.get_double_member ("g");
- var b = obj.get_double_member ("b");
- var a = obj.get_double_member ("a");
- rgba = Gdk.RGBA () { red = r, green = g, blue = b, alpha = a };
- hidden = obj.get_boolean_member ("hidden");
- }
-
- public Json.Node serialize () {
- var obj = new Json.Object ();
- obj.set_double_member ("r", rgba.red);
- obj.set_double_member ("g", rgba.green);
- obj.set_double_member ("b", rgba.blue);
- obj.set_double_member ("a", rgba.alpha);
- obj.set_boolean_member ("hidden", hidden);
- var node = new Json.Node (Json.NodeType.OBJECT);
- node.set_object (obj);
- return node;
- }
-
- // Mutators
- public Color with_hidden (bool hidden) {
- return Color (rgba.red, rgba.green, rgba.blue, rgba.alpha, hidden);
- }
-}
diff --git a/src/Lib/Components/CompiledBorder.vala b/src/Lib/Components/CompiledBorder.vala
deleted file mode 100644
index 0e788faae..000000000
--- a/src/Lib/Components/CompiledBorder.vala
+++ /dev/null
@@ -1,95 +0,0 @@
-/**
- * Copyright (c) 2019-2021 Alecaddd (https://alecaddd.com)
- *
- * This file is part of Akira.
- *
- * Akira 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.
-
- * Akira 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 Akira. If not, see .
- *
- * Authored by: Martin "mbfraga" Fraga
- */
-
-public class Akira.Lib.Components.CompiledBorder : Copyable {
- private Gdk.RGBA _color;
- private double _size;
- private bool _visible;
-
- public Gdk.RGBA color {
- get { return _color; }
- }
-
- public double size {
- get { return _size; }
- }
-
- public bool is_visible {
- get { return _visible; }
- }
-
- public CompiledBorder (Gdk.RGBA color, double size, bool visible) {
- _color = color;
- _size = size;
- _visible = visible;
- }
-
- public CompiledBorder.as_empty () {
- _color = Gdk.RGBA () { red = 0.0, green = 0.0, blue = 0.0, alpha = 0.0};
- _size = 0;
- _visible = false;
- }
-
- public CompiledBorder copy () {
- return new CompiledBorder (_color, _size, _visible);
- }
-
- public static CompiledBorder compile (Components? components, Lib.Items.ModelNode? node) {
- var rgba_border = Gdk.RGBA ();
- bool has_colors = false;
- double size = 0;
-
- if (components == null) {
- return new CompiledBorder (rgba_border, size, has_colors);
- }
-
- unowned var borders = components.borders;
- unowned var opacity = components.opacity;
-
- // Set an initial arbitrary color with full transparency.
- rgba_border.alpha = 0;
-
- if (borders == null) {
- return new CompiledBorder (rgba_border, size, false);
- }
-
- // Loop through all the configured borders and reload the color.
- for (var i = 0; i < borders.data.length; ++i) {
- // Skip if the border is hidden as we don't need to blend colors.
- if (borders.data[i].hidden) {
- continue;
- }
-
- // Set the new blended color.
- rgba_border = Utils.Color.blend_colors (rgba_border, borders.data[i].color);
- size = double.max (size, borders.data[i].size);
- has_colors = true;
- }
-
- // Apply the mixed RGBA value only if we had one.
- if (has_colors && opacity != null) {
- // Keep in consideration the global opacity to properly update the border color.
- rgba_border.alpha = rgba_border.alpha * opacity.opacity / 100;
- }
-
- return new CompiledBorder (rgba_border, size, has_colors && size != 0);
- }
-}
diff --git a/src/Lib/Components/CompiledFill.vala b/src/Lib/Components/CompiledFill.vala
deleted file mode 100644
index 106b23876..000000000
--- a/src/Lib/Components/CompiledFill.vala
+++ /dev/null
@@ -1,85 +0,0 @@
-/**
- * Copyright (c) 2019-2021 Alecaddd (https://alecaddd.com)
- *
- * This file is part of Akira.
- *
- * Akira 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.
-
- * Akira 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 Akira. If not, see .
- *
- * Authored by: Martin "mbfraga" Fraga
- */
-
-public class Akira.Lib.Components.CompiledFill : Copyable {
- private Gdk.RGBA _color;
- private bool _visible;
-
- public Gdk.RGBA color {
- get { return _color; }
- }
-
- public bool is_visible {
- get { return _visible; }
- }
-
- public CompiledFill (Gdk.RGBA color, bool visible) {
- _color = color;
- _visible = visible;
- }
-
- public CompiledFill.as_empty () {
- _color = Gdk.RGBA () { red = 0.0, green = 0.0, blue = 0.0, alpha = 0.0};
- _visible = false;
- }
-
- public CompiledFill copy () {
- return new CompiledFill (_color, _visible);
- }
-
- public static CompiledFill compile (Components? components, Lib.Items.ModelNode? node) {
- var rgba_fill = Gdk.RGBA ();
- bool has_colors = false;
- // Set an initial arbitrary color with full transparency.
- rgba_fill.alpha = 0;
-
- if (components == null) {
- return new CompiledFill (rgba_fill, has_colors);
- }
-
- unowned var fills = components.fills;
- unowned var opacity = components.opacity;
-
- if (fills == null) {
- return new CompiledFill (rgba_fill, has_colors);
- }
-
- // Loop through all the configured fills.
- for (var i = 0; i < fills.data.length; ++i) {
- // Skip if the fill is hidden as we don't need to blend colors.
- if (fills.data[i].hidden) {
- continue;
- }
-
- // Set the new blended color.
- rgba_fill = Utils.Color.blend_colors (rgba_fill, fills.data[i].color);
- has_colors = true;
- }
-
- // Apply the mixed RGBA value only if we had one.
- if (has_colors && opacity != null) {
- // Keep in consideration the global opacity to properly update the fill color.
- rgba_fill.alpha = rgba_fill.alpha * opacity.opacity / 100;
- }
-
- return new CompiledFill (rgba_fill, has_colors);
- }
-}
diff --git a/src/Lib/Components/CompiledGeometry.vala b/src/Lib/Components/CompiledGeometry.vala
deleted file mode 100644
index dba2db1d7..000000000
--- a/src/Lib/Components/CompiledGeometry.vala
+++ /dev/null
@@ -1,216 +0,0 @@
-/**
- * Copyright (c) 2019-2021 Alecaddd (https://alecaddd.com)
- *
- * This file is part of Akira.
- *
- * Akira 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.
-
- * Akira 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 Akira. If not, see .
- *
- * Authored by: Martin "mbfraga" Fraga
- */
-
-public class Akira.Lib.Components.CompiledGeometry : Copyable {
- public struct CompiledGeometryData {
- public Coordinates? source_center;
- public Size? source_size;
- public Transform? source_transform;
- public Cairo.Matrix _transformation_matrix;
- // Bounding box in local coordinates.
- public Geometry.Rectangle local_bb;
- // These rectangles are in global coordinates.
- public Geometry.Quad area;
- public Geometry.Quad drawable_area;
-
- // Cached bounding box that contains the rotated area.
- public Geometry.Rectangle area_bb;
-
- public CompiledGeometryData () {
- source_center = null;
- source_size = null;
- source_transform = null;
- }
- }
-
- public CompiledGeometryData _data;
-
- public Geometry.Rectangle local_bb { get { return _data.local_bb; }}
- public Geometry.Quad area { get { return _data.area; }}
- public Geometry.Rectangle area_bb { get { return _data.area_bb; }}
- public Geometry.Rectangle drawable_bb { get { return _data.drawable_area.bounding_box; }}
-
- public double source_width {
- get {
- return _data.source_size == null ? area_bb.width : _data.source_size.width;
- }
- }
-
- public double source_height {
- get {
- return _data.source_size == null ? area_bb.height : _data.source_size.height;
- }
- }
-
- public double tl_x { get { return _data.area.tl_x; }}
- public double tl_y { get { return _data.area.tl_y; }}
- public double tr_x { get { return _data.area.tr_x; }}
- public double tr_y { get { return _data.area.tr_y; }}
- public double bl_x { get { return _data.area.bl_x; }}
- public double bl_y { get { return _data.area.bl_y; }}
- public double br_x { get { return _data.area.br_x; }}
- public double br_y { get { return _data.area.br_y; }}
-
- public double bb_top { get { return _data.area_bb.top; }}
- public double bb_left { get { return _data.area_bb.left; }}
- public double bb_bottom { get { return _data.area_bb.bottom; }}
- public double bb_right { get { return _data.area_bb.right; }}
-
- public Cairo.Matrix transformation_matrix { get { return _data._transformation_matrix; }}
-
- public CompiledGeometry (CompiledGeometryData data) {
- _data = data;
- }
-
- public CompiledGeometry.as_empty () {
- _data = CompiledGeometryData ();
- _data.area = Geometry.Quad ();
- _data.area_bb = Geometry.Rectangle ();
- _data._transformation_matrix = Cairo.Matrix.identity ();
- }
-
- public CompiledGeometry copy () {
- return new CompiledGeometry (_data);
- }
-
- public CompiledGeometry.dummy () {
- _data = CompiledGeometryData ();
- }
-
- public CompiledGeometry.from_components (
- Components? components,
- Lib.Items.ModelNode? node,
- bool size_from_path = false
- ) {
- _data = CompiledGeometryData ();
-
- if (components == null) {
- return;
- }
-
- _data.source_center = components.center;
- _data.source_transform = components.transform;
-
- unowned var compiled_border = node.instance.compiled_border;
- var border_width = compiled_border == null ? 0 : compiled_border.size;
-
- assert (_data.source_center != null);
-
- if (_data.source_transform == null) {
- _data._transformation_matrix = Cairo.Matrix.identity ();
- } else {
- _data._transformation_matrix = _data.source_transform.transformation_matrix;
- }
-
- double width = 0;
- double height = 0;
-
- int border_overestimate = 1;
-
- if (size_from_path) {
- if (components.path == null) {
- _data.local_bb = Geometry.Rectangle ();
- _data.area = Geometry.Quad ();
- _data.area_bb = Geometry.Rectangle ();
- return;
- }
-
- var ext = components.path.calculate_extents ();
- width = ext.width;
- height = ext.height;
- _data.source_size = new Lib.Components.Size (ext.width, ext.height, false);
- border_overestimate = 4;
- } else {
- if (components.size == null) {
- _data.local_bb = Geometry.Rectangle ();
- _data.area = Geometry.Quad ();
- _data.area_bb = Geometry.Rectangle ();
- return;
- }
-
- _data.source_size = components.size;
- height = _data.source_size.height;
- width = _data.source_size.width;
- }
-
- var center_x = _data.source_center.x;
- var center_y = _data.source_center.y;
-
- var hw = width / 2.0;
- var hh = height / 2.0;
- _data.local_bb = Geometry.Rectangle.with_coordinates (-hw, -hh, hw, hh);
-
- _data.area = Geometry.Quad.from_components (center_x, center_y, width, height, _data._transformation_matrix);
-
- if (border_width > 0) {
- var bw = border_width * 2 * border_overestimate;
- _data.drawable_area = Geometry.Quad.from_components (center_x, center_y, width + bw, height + bw, _data._transformation_matrix);
- }
- else {
- _data.drawable_area = _data.area;
- }
-
- _data.area_bb = _data.area.bounding_box;
-
- _data._transformation_matrix.x0 = center_x;
- _data._transformation_matrix.y0 = center_y;
- }
-
- public static CompiledGeometry.from_descendants (Components? components, Lib.Items.ModelNode? node) {
- _data = CompiledGeometryData ();
- if (node == null || node.children == null) {
- return;
- }
-
- _data._transformation_matrix = Cairo.Matrix.identity ();
- _data.area.transformation = _data._transformation_matrix;
-
- double top = int.MAX;
- double bottom = int.MIN;
- double left = int.MAX;
- double right = int.MIN;
-
- foreach (var child in node.children.data) {
- unowned var cg = child.instance.compiled_geometry;
- if (cg == null) {
- continue;
- }
-
- top = double.min (top, cg.bb_top);
- bottom = double.max (bottom, cg.bb_bottom);
- left = double.min (left, cg.bb_left);
- right = double.max (right, cg.bb_right);
- }
-
- _data.area.tl_x = left;
- _data.area.tl_y = top;
- _data.area.tr_x = right;
- _data.area.tr_y = top;
- _data.area.bl_x = left;
- _data.area.bl_y = bottom;
- _data.area.br_x = right;
- _data.area.br_y = bottom;
-
- _data.drawable_area = _data.area;
- _data.local_bb = _data.area.bounding_box;
- _data.area_bb = _data.area.bounding_box;
- }
-}
diff --git a/src/Lib/Components/CompiledName.vala b/src/Lib/Components/CompiledName.vala
deleted file mode 100644
index e49fb55a4..000000000
--- a/src/Lib/Components/CompiledName.vala
+++ /dev/null
@@ -1,42 +0,0 @@
-/**
- * Copyright (c) 2021 Alecaddd (https://alecaddd.com)
- *
- * This file is part of Akira.
- *
- * Akira 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.
-
- * Akira 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 Akira. If not, see .
- *
- * Authored by: Alessandro "alecaddd" Castellani
- */
-
-public class Akira.Lib.Components.CompiledName : Copyable {
- private string _name = "";
-
- public string name {
- get {
- return _name;
- }
- }
-
- public CompiledName (string name) {
- _name = name;
- }
-
- public CompiledName.as_empty () {
- _name = "";
- }
-
- public CompiledName copy () {
- return new CompiledName (_name);
- }
-}
diff --git a/src/Lib/Components/Component.vala b/src/Lib/Components/Component.vala
deleted file mode 100644
index 3701e7bca..000000000
--- a/src/Lib/Components/Component.vala
+++ /dev/null
@@ -1,90 +0,0 @@
-/**
- * Copyright (c) 2019-2021 Alecaddd (https://alecaddd.com)
- *
- * This file is part of Akira.
- *
- * Akira 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.
-
- * Akira 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 Akira. If not, see .
- *
- * Authored by: Martin "mbfraga" Fraga
- */
-
-/*
- * Defines a copyable interface for components.
- */
-public interface Akira.Lib.Components.Copyable {
- public abstract T copy ();
-}
-
-/*
- * For now this is used as a namespace to hold some introspection.
- */
-public class Akira.Lib.Components.Component {
- /*
- * Serialize the details of a component to an existing component
- * object. This does not create a standalone node.
- */
- public virtual void serialize_details (ref Json.Object obj) {}
-
- public Json.Node serialize_component (string cname) {
- var obj = new Json.Object ();
- obj.set_string_member ("cname", cname);
- serialize_details (ref obj);
- var res = new Json.Node (Json.NodeType.OBJECT);
- res.set_object (obj);
- return res;
- }
-
- /*
- * Type of component.
- * For now this is only used for marking components dirty. It is technically
- * not necessary to have all components have anenum Type. Only the ones
- * that need respective View updates.
- */
- public enum Type {
- COMPILED_BORDER,
- COMPILED_FILL,
- COMPILED_GEOMETRY,
- COMPILED_NAME
- }
-
- public struct RegisteredType {
- public Type type;
- public bool dirty;
-
- public RegisteredType (Type t) {
- type = t;
- dirty = false;
- }
- }
-
- public struct RegisteredTypes {
- RegisteredType[] types;
-
- public RegisteredTypes () {
- types = new RegisteredType[4];
- types[0] = RegisteredType (Type.COMPILED_BORDER);
- types[1] = RegisteredType (Type.COMPILED_FILL);
- types[2] = RegisteredType (Type.COMPILED_GEOMETRY);
- types[3] = RegisteredType (Type.COMPILED_NAME);
- }
-
- public void mark_dirty (Type type, bool new_state) {
- for (var i = 0; i < types.length; ++i) {
- if (types[i].type == type) {
- types[i].dirty = new_state;
- }
- }
- }
- }
-}
diff --git a/src/Lib/Components/Components.vala b/src/Lib/Components/Components.vala
deleted file mode 100644
index b3802212d..000000000
--- a/src/Lib/Components/Components.vala
+++ /dev/null
@@ -1,282 +0,0 @@
-/**
- * Copyright (c) 2019-2021 Alecaddd (https://alecaddd.com)
- *
- * This file is part of Akira.
- *
- * Akira 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.
-
- * Akira 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 Akira. If not, see .
- *
- * Authored by: Martin "mbfraga" Fraga
- */
-
-public struct Akira.Lib.Components.CompiledComponents {
- public CompiledFill? compiled_fill;
- public CompiledBorder? compiled_border;
- public CompiledGeometry? compiled_geometry;
- public CompiledName? compiled_name;
-
- public bool is_empty { get {
- return compiled_fill == null
- && compiled_border == null
- && compiled_geometry == null
- && compiled_name == null;
- }}
-
- public Lib.Components.Component.RegisteredTypes dirty_components;
-
- public CompiledComponents () {
- compiled_fill = null;
- compiled_border = null;
- compiled_geometry = null;
- compiled_name = null;
- dirty_components = Lib.Components.Component.RegisteredTypes ();
- }
-
- /*
- * Sets a component null based on passed Type.
- * Returns false if component was already null.
- */
- public bool clear_component (Lib.Components.Component.Type comp_type) {
- switch (comp_type) {
- case Component.Type.COMPILED_BORDER: {
- if (compiled_border != null) {
- compiled_border = null;
- return true;
- }
- break;
- }
- case Component.Type.COMPILED_FILL: {
- if (compiled_fill != null) {
- compiled_fill = null;
- return true;
- }
- break;
- }
- case Component.Type.COMPILED_GEOMETRY: {
- if (compiled_geometry != null) {
- compiled_geometry = null;
- return true;
- }
- break;
- }
- case Component.Type.COMPILED_NAME: {
- if (compiled_name != null) {
- compiled_name = null;
- return true;
- }
- break;
- }
- default:
- break;
- }
- return false;
- }
-
- /*
- * Return true if new fill color was generated.
- */
- public bool maybe_compile_fill (Lib.Items.ModelType type, Components? components, Lib.Items.ModelNode? node) {
- if (compiled_fill != null) {
- return false;
- }
-
- compiled_fill = type.compile_fill (components, node);
-
- dirty_components.mark_dirty (Component.Type.COMPILED_FILL, true);
- return true;
- }
-
- /*
- * Return true if new border color was generated.
- */
- public bool maybe_compile_border (Lib.Items.ModelType type, Components? components, Lib.Items.ModelNode? node) {
- if (compiled_border != null) {
- return false;
- }
-
- compiled_border = type.compile_border (components, node);
- dirty_components.mark_dirty (Component.Type.COMPILED_BORDER, true);
- return true;
- }
-
- /*
- * Return true if new geometry was generated.
- */
- public bool maybe_compile_geometry (Lib.Items.ModelType type, Components? components, Lib.Items.ModelNode? node) {
- if (compiled_geometry != null) {
- return false;
- }
-
- compiled_geometry = type.compile_geometry (components, node);
- dirty_components.mark_dirty (Component.Type.COMPILED_GEOMETRY, true);
- return true;
- }
-
- public bool maybe_compile_name (Lib.Items.ModelType type, Components? components, Lib.Items.ModelNode? node) {
- if (compiled_name != null) {
- return false;
- }
-
- compiled_name = type.compile_name (components, node);
- dirty_components.mark_dirty (Component.Type.COMPILED_NAME, true);
- return true;
- }
-}
-
-public struct Akira.Lib.Components.Components {
- public Borders? borders;
- public BorderRadius? border_radius;
- public Fills? fills;
- public Flipped? flipped;
- public Layer? layer;
- public Name? name;
- public Opacity? opacity;
-
- public Coordinates? center;
- public Size? size;
- public Path? path;
- public Transform? transform;
- public Text? text;
-
- public Layout? layout;
-
- public Components () {
- borders = null;
- border_radius = null;
- fills = null;
- flipped = null;
- layer = null;
- name = null;
- opacity = null;
- center = null;
- size = null;
- path = null;
- transform = null;
- layout = null;
- text = null;
- }
-
- public static Name default_name () {
- return new Name ("item", "-1");
- }
-
- public static Opacity default_opacity () {
- return new Opacity (100.0);
- }
-
- public static Transform default_transform () {
- return new Transform.from_rotation (0.0);
- }
-
- public static Flipped default_flipped () {
- return new Flipped (false, false);
- }
-
- public static BorderRadius default_border_radius () {
- return new BorderRadius (0, 0, false, false);
- }
-
- public static Layer default_layer () {
- return new Layer (false);
- }
-
- public void serialize (ref Json.Builder builder) {
- builder.set_member_name ("components");
-
- {
- builder.begin_array ();
-
- if (borders != null) {
- builder.add_value (borders.serialize_component ("borders"));
- }
- if (border_radius != null) {
- builder.add_value (border_radius.serialize_component ("border_radius"));
- }
- if (fills != null) {
- builder.add_value (fills.serialize_component ("fills"));
- }
- if (flipped != null) {
- builder.add_value (flipped.serialize_component ("flipped"));
- }
- if (layer != null) {
- builder.add_value (layer.serialize_component ("layer"));
- }
- if (name != null) {
- builder.add_value (name.serialize_component ("name"));
- }
- if (center != null) {
- builder.add_value (center.serialize_component ("center"));
- }
- if (size != null) {
- builder.add_value (size.serialize_component ("size"));
- }
- if (path != null) {
- builder.add_value (path.serialize_component ("path"));
- }
- if (transform != null) {
- builder.add_value (transform.serialize_component ("transform"));
- }
- if (layout != null) {
- builder.add_value (layout.serialize_component ("layout"));
- }
- if (text != null) {
- builder.add_value (text.serialize_component ("text"));
- }
-
- builder.end_array ();
- }
- }
-
- public static Components deserialize (Json.Node? components) {
- var new_components = Components ();
-
- if (components == null) {
- return new_components;
- }
-
- foreach (unowned var comp_node in components.get_array ().get_elements ()) {
- unowned var comp_obj = comp_node.get_object ();
- assert (comp_obj != null);
- var cname = comp_obj.get_string_member ("cname");
-
- // Here we could probably use delegates in the future.
- if (cname == "borders") {
- new_components.borders = new Lib.Components.Borders.deserialized (comp_obj);
- } else if (cname == "border_radius") {
- new_components.border_radius = new Lib.Components.BorderRadius.deserialized (comp_obj);
- } else if (cname == "fills") {
- new_components.fills = new Lib.Components.Fills.deserialized (comp_obj);
- } else if (cname == "flipped") {
- new_components.flipped = new Lib.Components.Flipped.deserialized (comp_obj);
- } else if (cname == "layer") {
- new_components.layer = new Lib.Components.Layer.deserialized (comp_obj);
- } else if (cname == "name") {
- new_components.name = new Lib.Components.Name.deserialized (comp_obj);
- } else if (cname == "center") {
- new_components.center = new Lib.Components.Coordinates.deserialized (comp_obj);
- } else if (cname == "size") {
- new_components.size = new Lib.Components.Size.deserialized (comp_obj);
- } else if (cname == "path") {
- new_components.path = new Lib.Components.Path.deserialized (comp_obj);
- } else if (cname == "transform") {
- new_components.transform = new Lib.Components.Transform.deserialized (comp_obj);
- } else if (cname == "layout") {
- new_components.layout = new Lib.Components.Layout.deserialized (comp_obj);
- } else if (cname == "text") {
- new_components.text = new Lib.Components.Text.deserialized (comp_obj);
- }
- }
-
- return new_components;
- }
-}
diff --git a/src/Lib/Components/Coordinates.vala b/src/Lib/Components/Coordinates.vala
deleted file mode 100644
index 6542e30fb..000000000
--- a/src/Lib/Components/Coordinates.vala
+++ /dev/null
@@ -1,56 +0,0 @@
-/**
- * Copyright (c) 2019-2021 Alecaddd (https://alecaddd.com)
- *
- * This file is part of Akira.
- *
- * Akira 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.
-
- * Akira 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 Akira. If not, see .
- *
- * Authored by: Martin "mbfraga" Fraga
- */
-
-public class Akira.Lib.Components.Coordinates : Component, Copyable {
- private double _x;
- private double _y;
-
- public double x {
- get { return _x; }
- }
-
- public double y {
- get { return _y; }
- }
-
- public Coordinates (double x, double y) {
- _x = x;
- _y = y;
- }
-
- public Coordinates.deserialized (Json.Object obj) {
- _x = obj.get_double_member ("x");
- _y = obj.get_double_member ("y");
- }
-
- protected override void serialize_details (ref Json.Object obj) {
- obj.set_double_member ("x", _x);
- obj.set_double_member ("y", _y);
- }
-
- public Coordinates copy () {
- return new Coordinates (_x, _y);
- }
-
- public Coordinates translated (double dx, double dy) {
- return new Coordinates (_x + dx, _y + dy);
- }
-}
diff --git a/src/Lib/Components/Fills.vala b/src/Lib/Components/Fills.vala
deleted file mode 100644
index c9ea2f90c..000000000
--- a/src/Lib/Components/Fills.vala
+++ /dev/null
@@ -1,174 +0,0 @@
-/**
- * Copyright (c) 2019-2021 Alecaddd (https://alecaddd.com)
- *
- * This file is part of Akira.
- *
- * Akira 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.
-
- * Akira 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 Akira. If not, see .
- *
- * Authored by: Martin "mbfraga" Fraga
- */
-
-public class Akira.Lib.Components.Fills : Component, Copyable {
- public struct Fill {
- public int _id;
- public Color _color;
-
- public Fill (int id = -1, Color color = Color ()) {
- _id = id;
- _color = color;
- }
-
- public Fill.deserialized (int id, Json.Object obj) {
- _id = id;
- _color = Color.deserialized (obj.get_object_member ("color"));
- }
-
- // Recommended accessors.
- public int id {
- get {
- return _id;
- }
- }
- public Gdk.RGBA color {
- get {
- return _color.rgba;
- }
- }
- public bool hidden {
- get {
- return _color.hidden;
- }
- }
-
- // Mutators.
- public Fill with_color (Color new_color) {
- return Fill (_id, new_color);
- }
-
- public Json.Node serialize () {
- var obj = new Json.Object ();
- obj.set_int_member ("id", _id);
- obj.set_member ("color", _color.serialize ());
- var node = new Json.Node (Json.NodeType.OBJECT);
- node.set_object (obj);
- return node;
- }
- }
-
- public Fill[] data;
-
- public Fills () {
- data = new Fill[1];
- }
-
- public Fills.with_color (Color color) {
- data = new Fill[1];
- data[0] = Fill (0, color);
- }
-
- public Fills.deserialized (Json.Object obj) {
- var arr = obj.get_array_member ("fill_data").get_elements ();
- data = new Fill[0];
- var idx = 0;
- foreach (unowned var fill in arr) {
- data.resize (data.length + 1);
- data[idx] = Fill.deserialized (idx, fill.get_object ());
- ++idx;
- }
- }
-
- protected override void serialize_details (ref Json.Object obj) {
- var array = new Json.Array ();
-
- foreach (unowned var d in data) {
- array.add_element (d.serialize ());
- }
-
- var node = new Json.Node (Json.NodeType.ARRAY);
- node.set_array (array);
- obj.set_member ("fill_data", node);
- }
-
- public Fills copy () {
- var cln = new Fills ();
- cln.data = data;
- return cln;
- }
-
- // Recommended accessors.
- public Fill? fill_from_id (int id) {
- foreach (unowned var fill in data) {
- if (fill.id == id) {
- return fill.with_color (fill._color);
- }
- }
- return null;
- }
-
- public bool replace (Fill fill) {
- for (var i = 0; i < data.length; ++i) {
- if (data[i].id == fill.id) {
- data[i] = fill;
- return true;
- }
- }
- return false;
- }
-
- /*
- * Create a new Fill with the passed color and add it to the data structure.
- * It's up to the code requiring this to then replace the fills component.
- */
- public void append_fill_with_color (Color color) {
- int latest_id = int.MIN;
- foreach (unowned var fill in data) {
- latest_id = int.max (latest_id, fill.id);
- }
- latest_id++;
- var fill = Fill ((int) latest_id, color);
- data.resize (data.length + 1);
- data[data.length - 1] = fill;
- }
-
- // Todo...
- public void append_fill_with_image () {}
-
- // Todo...
- public void append_fill_with_gradient () {}
-
- // Todo...
- public void append_fill_with_pattern () {}
-
- public int remove (uint id) {
- var ct = 0;
- foreach (unowned var fill in data) {
- if (fill.id == id) {
- return remove_at (ct) ? 1 : -1;
- }
- ++ct;
- }
- return -1;
- }
-
- private bool remove_at (int pos) {
- if (pos >= data.length || pos < 0) {
- assert (false);
- return false;
- }
-
- data.move (pos + 1, pos, data.length - pos - 1);
- data.resize (data.length - 1);
- return true;
- }
- }
diff --git a/src/Lib/Components/Flipped.vala b/src/Lib/Components/Flipped.vala
deleted file mode 100644
index e52da12ea..000000000
--- a/src/Lib/Components/Flipped.vala
+++ /dev/null
@@ -1,53 +0,0 @@
-/**
- * Copyright (c) 2019-2021 Alecaddd (https://alecaddd.com)
- *
- * This file is part of Akira.
- *
- * Akira 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.
-
- * Akira 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 Akira. If not, see .
- *
- * Authored by: Martin "mbfraga" Fraga
- */
-
-
-public class Akira.Lib.Components.Flipped : Component, Copyable {
- private bool _horizontal;
- private bool _vertical;
-
- public bool horizontal {
- get { return _horizontal; }
- }
-
- public bool vertical {
- get { return _vertical; }
- }
-
- public Flipped (bool horizontal, bool vertical) {
- _horizontal = horizontal;
- _vertical = vertical;
- }
-
- public Flipped.deserialized (Json.Object obj) {
- _horizontal = obj.get_boolean_member ("horizontal");
- _vertical = obj.get_boolean_member ("vertical");
- }
-
- protected override void serialize_details (ref Json.Object obj) {
- obj.set_boolean_member ("horizontal", _horizontal);
- obj.set_boolean_member ("vertical", _vertical);
- }
-
- public Flipped copy () {
- return new Flipped (horizontal, vertical);
- }
-}
diff --git a/src/Lib/Components/Layer.vala b/src/Lib/Components/Layer.vala
deleted file mode 100644
index d6d0c52d9..000000000
--- a/src/Lib/Components/Layer.vala
+++ /dev/null
@@ -1,48 +0,0 @@
-/**
- * Copyright (c) 2019-2021 Alecaddd (https://alecaddd.com)
- *
- * This file is part of Akira.
- *
- * Akira 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.
-
- * Akira 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 Akira. If not, see .
- *
- * Authored by: Martin "mbfraga" Fraga
- */
-
-public class Akira.Lib.Components.Layer : Component, Copyable {
- private bool _locked;
-
- public bool locked {
- get { return _locked; }
- }
-
- public Layer (bool locked) {
- _locked = locked;
- }
-
- public Layer.deserialized (Json.Object obj) {
- _locked = obj.get_boolean_member ("locked");
- }
-
- protected override void serialize_details (ref Json.Object obj) {
- obj.set_boolean_member ("locked", _locked);
- }
-
- public Layer copy () {
- return new Layer (_locked);
- }
-
- public Layer with_locked (bool new_locked) {
- return new Layer (new_locked);
- }
-}
diff --git a/src/Lib/Components/Layout.vala b/src/Lib/Components/Layout.vala
deleted file mode 100644
index ecb243d3c..000000000
--- a/src/Lib/Components/Layout.vala
+++ /dev/null
@@ -1,61 +0,0 @@
-/**
- * Copyright (c) 2019-2021 Alecaddd (https://alecaddd.com)
- *
- * This file is part of Akira.
- *
- * Akira 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.
-
- * Akira 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 Akira. If not, see .
- *
- * Authored by: Martin "mbfraga" Fraga
- */
-
- /*
- * Defines how children will behave while in affine transforms.
- * For now the options are quite simple, in the future more data
- * and context could be added for more complex layouts.
- */
-public class Akira.Lib.Components.Layout : Component, Copyable {
- public struct LayoutData {
- public bool can_rotate;
- public bool dilated_resize;
- public bool clips_children;
- }
-
- // main data for boxed Fill
- private LayoutData _data;
-
- public Layout (LayoutData data) {
- _data = data;
- }
-
- public Layout.deserialized (Json.Object obj) {
- _data.can_rotate = obj.get_boolean_member ("can_rotate");
- _data.dilated_resize = obj.get_boolean_member ("dilated_resize");
- _data.clips_children = obj.get_boolean_member ("clips_children");
- }
-
- protected override void serialize_details (ref Json.Object obj) {
- obj.set_boolean_member ("can_rotate", can_rotate);
- obj.set_boolean_member ("dilated_resize", dilated_resize);
- obj.set_boolean_member ("clips_children", clips_children);
- }
-
- public Layout copy () {
- return new Layout (_data);
- }
-
- // Recommended accessors
- public bool can_rotate { get { return _data.can_rotate; } }
- public bool dilated_resize { get { return _data.dilated_resize; } }
- public bool clips_children { get { return _data.clips_children; } }
-}
diff --git a/src/Lib/Components/Name.vala b/src/Lib/Components/Name.vala
deleted file mode 100644
index cf919667f..000000000
--- a/src/Lib/Components/Name.vala
+++ /dev/null
@@ -1,60 +0,0 @@
-/**
- * Copyright (c) 2019-2021 Alecaddd (https://alecaddd.com)
- *
- * This file is part of Akira.
- *
- * Akira 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.
-
- * Akira 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 Akira. If not, see .
- *
- * Authored by: Martin "mbfraga" Fraga
- */
-
-public class Akira.Lib.Components.Name : Component, Copyable {
- private string _id;
- private string _name;
- private string _filename;
-
- public string id {
- get { return _id; }
- }
-
- public string name {
- get { return _name; }
- }
-
- public string filename {
- get { return _filename; }
- }
-
- public Name (string name, string id, string? filename = null) {
- _id = id;
- _name = name;
- _filename = filename != null ? filename : name;
- }
-
- public Name.deserialized (Json.Object obj) {
- _id = obj.get_string_member ("id");
- _name = obj.get_string_member ("name");
- _filename = obj.get_string_member ("filename");
- }
-
- protected override void serialize_details (ref Json.Object obj) {
- obj.set_string_member ("id", _id);
- obj.set_string_member ("name", _name);
- obj.set_string_member ("filename", _filename);
- }
-
- public Name copy () {
- return new Name (_name, _id, _filename);
- }
-}
diff --git a/src/Lib/Components/Opacity.vala b/src/Lib/Components/Opacity.vala
deleted file mode 100644
index 19eccaab9..000000000
--- a/src/Lib/Components/Opacity.vala
+++ /dev/null
@@ -1,49 +0,0 @@
-/**
- * Copyright (c) 2019-2021 Alecaddd (https://alecaddd.com)
- *
- * This file is part of Akira.
- *
- * Akira 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.
-
- * Akira 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 Akira. If not, see .
- *
- * Authored by: Martin "mbfraga" Fraga
- */
-
-public class Akira.Lib.Components.Opacity : Component, Copyable {
- private double _opacity;
-
- public double opacity {
- get { return _opacity; }
- }
-
- public Opacity (double opacity) {
- if (opacity < 0.0) {
- _opacity = 0.0;
- return;
- }
-
- _opacity = opacity <= 100.0 ? opacity : 100.0;
- }
-
- public Opacity.deserialized (Json.Object obj) {
- _opacity = obj.get_double_member ("opacity");
- }
-
- protected override void serialize_details (ref Json.Object obj) {
- obj.set_double_member ("opacity", _opacity);
- }
-
- public Opacity copy () {
- return new Opacity (_opacity);
- }
-}
diff --git a/src/Lib/Components/Path.vala b/src/Lib/Components/Path.vala
deleted file mode 100644
index 4b5cab936..000000000
--- a/src/Lib/Components/Path.vala
+++ /dev/null
@@ -1,106 +0,0 @@
-/**
- * Copyright (c) 2019-2021 Alecaddd (https://alecaddd.com)
- *
- * This file is part of Akira.
- *
- * Akira 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.
-
- * Akira 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 Akira. If not, see .
- *
- * Authored by: Martin "mbfraga" Fraga
- * Modified by: Ashish Shevale
- */
-
-public class Akira.Lib.Components.Path : Component, Copyable {
- // Control points relative to a top-left of 0,0.
- // In the future we will probably want control points with more data.
- public Geometry.PathSegment[] data;
- public bool close = false;
-
- public Path (bool close = false) {
- data = new Geometry.PathSegment[0];
- this.close = close;
- }
-
- public Path.from_single_point (Geometry.Point pt, bool close = false) {
- data = new Geometry.PathSegment[1];
-
- // Only a line can be created from a single point. No need to check command.
- data[0] = Geometry.PathSegment.line (pt);
-
- this.close = close;
- }
-
- public Path.from_points (Geometry.PathSegment[] data, bool close = false) {
- this.data = data;
- this.close = close;
- }
-
- public Path.deserialized (Json.Object obj) {
- var arr = obj.get_array_member ("path_data").get_elements ();
- data = new Geometry.PathSegment[0];
- var idx = 0;
-
- foreach (unowned var pt in arr) {
- data.resize (data.length + 1);
- data[idx] = Geometry.PathSegment.deserialized (pt.get_object ());
- ++idx;
- }
- }
-
- protected override void serialize_details (ref Json.Object obj) {
- var array = new Json.Array ();
-
- foreach (unowned var d in data) {
- array.add_element (d.serialize ());
- }
-
- var node = new Json.Node (Json.NodeType.ARRAY);
- node.set_array (array);
- obj.set_member ("path_data", node);
- }
-
- public Path copy () {
- var cln = new Path ();
- cln.data = data;
- cln.close = close;
- return cln;
- }
-
- public Geometry.Rectangle calculate_extents () {
- // The minimum values need to be large for finding minimum to work.
- Geometry.Rectangle extents = Geometry.Rectangle ();
- extents.top = extents.left = double.MAX;
- extents.bottom = extents.right = double.MIN;
-
- for (int i = 0; i < data.length; ++i) {
- var segment = data[i];
-
- if (segment.type == Lib.Modes.PathEditMode.Type.LINE) {
- var point = segment.line_end;
- extents.left = double.min (extents.left, point.x);
- extents.right = double.max (extents.right, point.x);
- extents.top = double.min (extents.top, point.y);
- extents.bottom = double.max (extents.bottom, point.y);
- } else {
- var seg_extents = Utils.GeometryMath.calculate_bounds_for_curve (segment, data[i - 1].last_point);
-
- extents.left = double.min (extents.left, seg_extents.left);
- extents.top = double.min (extents.top, seg_extents.top);
- extents.right = double.max (extents.right, seg_extents.right);
- extents.bottom = double.max (extents.bottom, seg_extents.bottom);
- }
- }
-
- return extents;
- }
-}
diff --git a/src/Lib/Components/Size.vala b/src/Lib/Components/Size.vala
deleted file mode 100644
index 58916e9ae..000000000
--- a/src/Lib/Components/Size.vala
+++ /dev/null
@@ -1,72 +0,0 @@
-/**
- * Copyright (c) 2019-2021 Alecaddd (https://alecaddd.com)
- *
- * This file is part of Akira.
- *
- * Akira 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.
-
- * Akira 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 Akira. If not, see .
- *
- * Authored by: Martin "mbfraga" Fraga
- */
-
-public class Akira.Lib.Components.Size : Component, Copyable {
- private double _width;
- private double _height;
- private bool _locked;
-
- public double width {
- get { return _width; }
- }
-
- public double height {
- get { return _height; }
- }
-
- public bool locked {
- get { return _locked; }
- }
-
- public double ratio {
- get { return _height == 0 ? 0.0 : _width / _height; }
- }
-
- public Size (double width, double height, bool locked) {
- _locked = locked;
- _width = width;
- _height = height;
- }
-
- public Size.deserialized (Json.Object obj) {
- _width = obj.get_double_member ("width");
- _height = obj.get_double_member ("height");
- _locked = obj.get_boolean_member ("locked");
- }
-
- protected override void serialize_details (ref Json.Object obj) {
- obj.set_double_member ("width", _width);
- obj.set_double_member ("height", _height);
- obj.set_boolean_member ("locked", _locked);
- }
-
- public Size copy () {
- return new Size (_width, _height, _locked);
- }
-
- public Size with_width (double new_width) {
- return new Size (new_width, _height, _locked);
- }
-
- public Size with_height (double new_height) {
- return new Size (_width, new_height, _locked);
- }
-}
diff --git a/src/Lib/Components/Text.vala b/src/Lib/Components/Text.vala
deleted file mode 100644
index b77149d02..000000000
--- a/src/Lib/Components/Text.vala
+++ /dev/null
@@ -1,42 +0,0 @@
-/**
- * Copyright (c) 2019-2021 Alecaddd (https://alecaddd.com)
- *
- * This file is part of Akira.
- *
- * Akira 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.
-
- * Akira 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 Akira. If not, see .
- *
- * Authored by: Martin "mbfraga" Fraga
- */
-
-public class Akira.Lib.Components.Text : Component, Copyable {
- private string p_text;
-
- public string text { get { return p_text; } }
-
- public Text (string new_text) {
- p_text = new_text;
- }
-
- public Text.deserialized (Json.Object obj) {
- p_text = obj.get_string_member ("text");
- }
-
- protected override void serialize_details (ref Json.Object obj) {
- obj.set_string_member ("text", p_text);
- }
-
- public Text copy () {
- return new Text (p_text);
- }
-}
diff --git a/src/Lib/Components/Transform.vala b/src/Lib/Components/Transform.vala
deleted file mode 100644
index c1b11e357..000000000
--- a/src/Lib/Components/Transform.vala
+++ /dev/null
@@ -1,118 +0,0 @@
-/**
- * Copyright (c) 2019-2021 Alecaddd (https://alecaddd.com)
- *
- * This file is part of Akira.
- *
- * Akira 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.
-
- * Akira 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 Akira. If not, see .
- *
- * Authored by: Martin "mbfraga" Fraga
- */
-
-public class Akira.Lib.Components.Transform : Component, Copyable {
- private double _rotation = 0.0;
- private double _scale_x = 1.0;
- private double _scale_y = 1.0;
- private double _skew_xy = 0.0;
- private double _skew_yx = 0.0;
-
- public double rotation { get { return _rotation; } }
- public double rotation_in_degrees { get { return _rotation * 180 / GLib.Math.PI; } }
-
- public Cairo.Matrix rotation_matrix {
- get {
- var mat = Cairo.Matrix.identity ();
- mat.rotate (_rotation);
- return mat;
- }
- }
-
- public Cairo.Matrix scale_matrix {
- get {
- var mat = Cairo.Matrix.identity ();
- mat.scale (_scale_x, _scale_y);
- return mat;
- }
- }
-
- public Cairo.Matrix skew_matrix {
- get {
- var mat = Cairo.Matrix.identity ();
- mat.xy = _skew_xy;
- mat.yx = _skew_yx;
- return mat;
- }
- }
-
- public Cairo.Matrix transformation_matrix {
- get {
- Cairo.Matrix mat;
- Utils.GeometryMath.recompose_matrix (out mat, _scale_x, _scale_y, _skew_xy, _rotation);
- return mat;
- }
- }
-
- public Transform (
- double radians,
- double scale_x,
- double scale_y,
- double skew_xy,
- double skew_yx
- ) {
- _rotation = radians;
- _scale_x = scale_x;
- _scale_y = scale_y;
- _skew_xy = skew_xy;
- _skew_yx = skew_yx;
- }
-
- public Transform.from_rotation (double in_radians) {
- _rotation = in_radians;
- }
-
- public Transform.deserialized (Json.Object obj) {
- _rotation = obj.get_double_member ("rotation");
- _scale_x = obj.get_double_member ("scale_x");
- _scale_y = obj.get_double_member ("scale_y");
- _skew_xy = obj.get_double_member ("skew_xy");
- _skew_yx = obj.get_double_member ("skew_yx");
- }
-
- protected override void serialize_details (ref Json.Object obj) {
- obj.set_double_member ("rotation", _rotation);
- obj.set_double_member ("scale_x", _scale_x);
- obj.set_double_member ("scale_y", _scale_y);
- obj.set_double_member ("skew_xy", _skew_xy);
- obj.set_double_member ("skew_yx", _skew_yx);
- }
-
- public Transform copy () {
- return new Transform (
- _rotation,
- _scale_x,
- _scale_y,
- _skew_xy,
- _skew_yx
- );
- }
-
- public Transform with_main_rotation (double in_radians) {
- return new Transform (
- in_radians,
- _scale_x,
- _scale_y,
- _skew_xy,
- _skew_yx
- );
- }
-}
diff --git a/src/Lib/Items/ItemSelection.vala b/src/Lib/Items/ItemSelection.vala
deleted file mode 100644
index 3396a9886..000000000
--- a/src/Lib/Items/ItemSelection.vala
+++ /dev/null
@@ -1,258 +0,0 @@
-/**
- * Copyright (c) 2019-2021 Alecaddd (https://alecaddd.com)
- *
- * This file is part of Akira.
- *
- * Akira 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.
-
- * Akira 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 Akira. If not, see .
- *
- * Authored by: Martin "mbfraga" Fraga
- */
-
-/*
- * A selection of items with some useful accessors.
- */
-public class Akira.Lib.Items.NodeSelection : Object {
- private class ParentInfo {
- public uint children_selected_ct = 1;
- }
-
- // Used to determine first and last added nodes
- private uint last_added_sid = 0;
-
- public class SelectedNode {
- public ModelNode node;
- public int parent_id;
- public uint sid;
-
- public SelectedNode (ModelNode node, uint sid) {
- this.node = node;
- this.parent_id = node.parent.id;
- this.sid = sid;
- }
- }
-
- public Gee.HashSet groups;
- public Gee.TreeMap nodes;
-
- private Gee.HashMap parent_data;
-
- public NodeSelection (ModelNode? node) {
- groups = new Gee.HashSet ();
- nodes = new Gee.TreeMap ();
- parent_data = new Gee.HashMap ();
-
- if (node != null) {
- add_node (node);
- }
- }
-
- public ModelNode? first_node () {
- if (nodes.size == 0) {
- return null;
- }
-
- var it = nodes.map_iterator ();
- it.next ();
- return it.get_value ().node;
- }
-
- /*
- * Returns true if the selection only spans a single group. Meaning all selected items reside in a single group.
- * If true, the group id will be populated. Otherwise -1 is populated.
- */
- public bool spans_one_group (out int group_id) {
- group_id = -1;
-
- if (parent_data.size == 1) {
- foreach (var k in parent_data.keys) {
- group_id = k;
- return true;
- }
- }
- return false;
- }
-
- public void add_node (ModelNode to_add) {
- assert (to_add.parent != null);
- if (has_id (to_add.id, false)) {
- return;
- }
-
- // If any ancestor is selected
- if (ancestor_selected (to_add)) {
- return;
- }
-
- var cand = new SelectedNode (to_add, ++last_added_sid);
- nodes[to_add.id] = cand;
- register_parent (cand.parent_id);
-
- if (to_add.instance.is_group) {
- groups.add (to_add.id);
-
- var to_del = new GLib.Array ();
- foreach (var test in nodes.keys) {
- if (to_add.has_child (test)) {
- to_del.append_val (test);
- }
- }
-
- foreach (var did in to_del.data) {
- nodes.unset (did);
- }
- }
- }
-
- public void remove_node (int id) {
- if (nodes.has_key (id)) {
- deregister_parent (nodes[id].parent_id);
- nodes.unset (id);
- }
-
- if (groups.contains (id)) {
- groups.remove (id);
- }
- }
-
- public bool has_id (int id, bool nested) {
- if (nodes.has_key (id)) {
- return true;
- }
-
- if (groups.contains (id)) {
- return true;
- }
-
- if (!nested) {
- return false;
- }
-
- foreach (var group in groups) {
- if (nodes[group].node.has_child (id)) {
- return true;
- }
- }
-
- return false;
- }
-
- public bool is_empty () {
- return nodes.size == 0;
- }
-
- public int count () {
- return nodes.size;
- }
-
- public Geometry.TransformedRectangle area () {
-
- if (nodes.size == 0) {
- return Geometry.TransformedRectangle.empty ();
- }
-
- if (nodes.size == 1) {
- unowned var geom = first_node ().instance.compiled_geometry;
- return Geometry.TransformedRectangle () {
- matrix = geom.transformation_matrix,
- rect = geom.local_bb
- };
- }
-
- double top = int.MAX;
- double bottom = int.MIN;
- double left = int.MAX;
- double right = int.MIN;
-
- foreach (var node in nodes.values) {
- unowned var inst = node.node.instance;
- top = double.min (top, inst.bounding_box.top);
- bottom = double.max (bottom, inst.bounding_box.bottom);
- left = double.min (left, inst.bounding_box.left);
- right = double.max (right, inst.bounding_box.right);
- }
-
- return Geometry.TransformedRectangle () {
- matrix = Cairo.Matrix.identity (),
- rect = Geometry.Rectangle () {
- top = top,
- right = right,
- left = left,
- bottom = bottom,
- }
- };
- }
-
- public void nob_coordinates (Utils.Nobs.Nob nob, double scale, ref double x, ref double y) {
- Utils.Nobs.nob_xy_from_coordinates (nob, area ().quad (), scale, ref x, ref y);
- }
-
- public Geometry.Rectangle bounding_box () {
- var result = Geometry.Rectangle ();
- if (nodes.size == 0) {
- return result;
- }
-
- var top = double.MAX;
- var bottom = double.MIN;
- var left = double.MAX;
- var right = double.MIN;
-
- foreach (var node in nodes.values) {
- unowned var inst = node.node.instance;
- top = double.min (top, inst.bounding_box.top);
- bottom = double.max (bottom, inst.bounding_box.bottom);
- left = double.min (left, inst.bounding_box.left);
- right = double.max (right, inst.bounding_box.right);
- }
-
- result.top = top;
- result.bottom = bottom;
- result.left = left;
- result.right = right;
- return result;
- }
-
- private bool ancestor_selected (ModelNode target) {
- var parent = target.parent;
- while (parent.id != Model.ORIGIN_ID) {
- if (groups.contains (parent.id)) {
- return true;
- }
- parent = parent.parent;
- }
-
- return false;
- }
-
- private void register_parent (int parent_id) {
- if (parent_data.has_key (parent_id)) {
- parent_data[parent_id].children_selected_ct++;
- return;
- }
- parent_data[parent_id] = new ParentInfo ();
- }
-
- private void deregister_parent (int parent_id) {
- if (parent_data.has_key (parent_id)) {
- parent_data[parent_id].children_selected_ct--;
-
- if (parent_data[parent_id].children_selected_ct == 0) {
- parent_data.unset (parent_id);
- }
- return;
- }
-
- assert (false);
- }
-}
diff --git a/src/Lib/Items/Model.vala b/src/Lib/Items/Model.vala
deleted file mode 100644
index d574c9ec6..000000000
--- a/src/Lib/Items/Model.vala
+++ /dev/null
@@ -1,795 +0,0 @@
-/**
- * Copyright (c) 2019-2021 Alecaddd (https://alecaddd.com)
- *
- * This file is part of Akira.
- *
- * Akira 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.
-
- * Akira 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 Akira. If not, see .
- *
- * Authored by: Martin "mbfraga" Fraga
- * Authored by: Alessandro "alecaddd" Castellani
- *
- * Many of the methods inside this code base come from the Fireloom code base.
- * https://gitlab.com/mbfraga/fireloom_core
- */
-
-public interface Akira.Lib.Items.ModelListener : Object {
- public abstract void on_item_added (int id);
- public abstract void on_item_geometry_changed (int id);
- public abstract void on_items_deleted (GLib.Array ids);
- public abstract void on_item_transferred (int id);
-}
-
-/*
- * Holds maps to instances that define connectivity between items and groups.
- * Holds a dag based on nodes (starting from an origin node with `origin_id`.
- *
- * The dag needs to be rebuilt any time group topologies change. Changes that don't
- * affect groups generally don't need to have the dag rebuilt. Rebuilding a dag
- * repopulates all group nodes, but not item nodes. Item nodes can only have
- * a single parent and no children, and they are populated when an operation changes them.
- *
- * The reason changes to items (add/remove/restack) don't require the dag to be rebuilt
- * is for performance reasons--and the simplicity of their topology (single parent, no children).
- *
- * Group topologies rebuild the dag because in general those topologies will be small, and
- * it ascertains that the dag is true and minimizes boilerplate code that is very tricky to
- * begin with.
- */
-public class Akira.Lib.Items.Model : Object {
- public const int ORIGIN_ID = 5;
- public const int GROUP_START_ID = 10;
- public const int ITEM_START_ID = 10000000;
-
- private int last_group_id = GROUP_START_ID;
- private int last_item_id = ITEM_START_ID;
-
- public Gee.HashMap group_map;
- public Gee.HashMap item_map;
-
- public Gee.HashMap group_nodes;
- public Gee.HashMap item_nodes;
-
- public Gee.HashSet changed_items;
- public Gee.HashSet changed_groups;
-
- private ModelListener listener = null;
-
- private unowned ViewLayers.BaseCanvas? canvas = null;
-
- public Model () {
- item_map = new Gee.HashMap ();
- group_map = new Gee.HashMap ();
- item_nodes = new Gee.HashMap ();
- group_nodes = new Gee.HashMap ();
-
- changed_items = new Gee.HashSet ();
- changed_groups = new Gee.HashSet ();
-
- var group_instance = new ModelInstance (ORIGIN_ID, new ModelTypeGroup ());
- add_to_maps (new ModelNode (group_instance, 0), false);
- }
-
- public Model.live_model (ModelListener listener, ViewLayers.BaseCanvas? canvas) {
- this ();
-
- this.listener = listener;
- this.canvas = canvas;
- }
-
- public Model.clone (Model other) {
- this ();
-
- canvas = other.canvas;
- this.listener = null;
- last_group_id = other.last_group_id;
- last_item_id = other.last_item_id;
-
- foreach (var item in other.item_map) {
- item_map[item.key] = item.value.clone (true);
- }
-
- foreach (var group in other.group_map) {
- group_map[group.key] = group.value.clone (true);
- }
-
- }
-
- /*
- * Makes the model not be in a live state.
- */
- public void sleep () {
- listener = null;
- }
-
- /*
- * Makes the model live.
- */
- public void wake (ModelListener listener, bool regenerate) {
- this.listener = listener;
- if (regenerate) {
- var origin_node = node_from_id (ORIGIN_ID);
- var origin_instance = instance_from_id (ORIGIN_ID);
- origin_node.instance = origin_instance;
- regenerate_node (origin_node);
- }
- }
-
- public void compile_geometries () {
- internal_compile_geometries ();
- }
-
- public ModelInstance? instance_from_id (int id) {
- if (id >= ITEM_START_ID) {
- return item_map.get (id);
- }
-
- return group_map.get (id);
- }
-
- public ModelInstance? child_instance_at (int parent_id, int pos) {
- if (parent_id >= ITEM_START_ID) {
- // items don't have children
- return null;
- }
-
- var node = node_from_id (parent_id);
-
- if (node == null || pos >= node.children.length) {
- return null;
- }
-
- return node.children.index (pos).instance;
- }
-
- public ModelNode? node_from_id (int id) {
- if (id >= ITEM_START_ID) {
- return item_nodes.get (id);
- }
-
- return group_nodes.get (id);
- }
-
- public string path_from_id (int id) {
- return path_from_node (node_from_id (id));
- }
-
- public string path_from_node (ModelNode node) {
- if (node == null) {
- return "";
- }
-
- var builder = new GLib.StringBuilder ();
- build_path_recursive (node, ref builder);
- return builder.str;
- }
-
- /*
- * Build an array of int representing the path IDs of a node. This path is
- * unique for each node and changes based on the position relative to its
- * parent.
- */
- public int[] array_path_from_node (ModelNode node) {
- Array path = new Array ();
- build_array_path_recursive (node, ref path);
-
- return path.data;
- }
-
- public GLib.Array children_in_group (int group_id) {
- var group = group_nodes.get (group_id);
- return group == null ? new GLib.Array () : group.children;
- }
-
- public void alert_item_changed (int id, Components.Component.Type aspect_changed) {
- var node = node_from_id (id);
- if (node == null) {
- assert (false);
- return;
- }
-
- alert_node_changed (node, aspect_changed);
- }
-
- public void alert_node_changed (Lib.Items.ModelNode node, Components.Component.Type aspect_changed) {
- internal_alert_item_change (node, false, aspect_changed);
- }
-
- public void recalculate_children_stacking (int parent_id) {
- var group = group_nodes.get (parent_id);
- if (group == null) {
- assert (false);
- return;
- }
-
- internal_recalculate_children_stacking (group);
- }
-
- /*
- TODO: Finish the transfer method based on
- https://gitlab.com/mbfraga/fireloom_core/-/blob/main/packages/flmd/flmd_ItemModel.cpp#L148
- */
- public int transfer (
- int source_id,
- int source_pos,
- int num_items,
- int target_id,
- int target_pos,
- bool restack = false,
- Utils.TrivialDelegate? prep_for_op = null
- ) {
- if (num_items == 0) {
- return 0;
- }
-
- var source_node = node_from_id (source_id);
- var target_node = node_from_id (target_id);
-
- if (!(source_node is Lib.Items.ModelNode) || !(target_node is Lib.Items.ModelNode)) {
- assert (false);
- return -1;
- }
-
- unowned var source_children = source_node.children;
- int source_children_size = (int) source_children.length;
-
- if (source_pos >= source_children_size || source_pos + num_items > source_children_size) {
- assert (false);
- return -1;
- }
-
- if (source_id == target_id) {
- // TODO: shift instead
- assert (false);
- return -1;
- }
-
- unowned var target_children = target_node.children;
- int target_children_size = (int) target_children.length;
-
- if (target_pos >= target_children_size) {
- target_pos = target_children_size;
- }
-
- if (source_id != ORIGIN_ID && target_id != ORIGIN_ID) {
- // check for cycle
- for (var i = source_pos; i < source_pos + num_items; ++i) {
- unowned var node = source_children.index (i);
- if (node.id == target_id || target_node.has_ancestor (node.id, true)) {
- assert (false);
- return -1;
- }
- }
- }
-
- if (prep_for_op != null) {
- prep_for_op ();
- }
-
- var target_start_num_of_children = target_children.length;
-
- target_children.insert_vals (target_pos, source_children.data[source_pos : source_pos + num_items] , num_items);
-
- Utils.Array.insert_array_at_iarray (
- ref target_node.instance.children,
- target_pos,
- source_node.instance.children [source_pos : source_pos + num_items]
- );
-
- source_children.remove_range (source_pos, num_items);
- Utils.Array.remove_from_iarray (
- ref source_node.instance.children,
- source_pos,
- num_items
- );
-
- if (restack) {
- for (var i = source_pos; i < source_children.length; ++i) {
- source_children.index (i).pos_in_parent = i;
- }
- }
-
- var target_count = target_pos >= target_start_num_of_children ? target_start_num_of_children : target_pos;
-
- var added_count = 0;
-
- for (var i = target_count; i < target_children.length; ++i) {
- unowned var tgt = target_children.index (i);
-
- // Updating the parent is mandatory for nodes within the transfered range.
- tgt.pos_in_parent = (int)(target_count + added_count++);
- tgt.parent = target_node;
-
- if (!restack && added_count > num_items) {
- // we need to set the new parent regardless. But further restacking is unnecessary
- break;
- }
-
- internal_alert_item_change (tgt, false, Components.Component.Type.COMPILED_GEOMETRY);
- }
-
- if (source_node.id != ORIGIN_ID) {
- internal_alert_item_change (source_node, false, Components.Component.Type.COMPILED_GEOMETRY);
- }
-
- return 0;
- }
-
- public int remove (int id, bool restack) {
- var node = node_from_id (id);
-
- if (node == null) {
- return -1;
- }
-
- return extripate (node.parent.id, node.pos_in_parent, restack);
- }
-
- public int extripate (int parent_id, uint pos, bool restack) {
- var parent_node = group_nodes.get (parent_id);
-
- if (parent_node == null || pos >= parent_node.children.length) {
- return -1;
- }
-
- unowned var target_node = parent_node.children.index (pos);
-
- inner_remove (parent_node, target_node, pos);
-
- if (restack) {
- for (var i = (int)pos; i < parent_node.children.length; ++i) {
- parent_node.children.index (i).pos_in_parent--;
- }
- }
- return 0;
- }
-
- public int append_new_item (int parent_id, Lib.Items.ModelInstance candidate) {
- var parent_node = group_nodes.get (parent_id);
- if (parent_node == null) {
- return -1;
- }
-
- var pos = parent_node.children == null ? 0 : parent_node.children.length;
- return inner_splice_new_item (parent_node, pos, candidate);
- }
-
- public int splice_new_item (int parent_id, uint pos, Lib.Items.ModelInstance candidate) {
- var parent_node = group_nodes.get (parent_id);
- if (parent_node == null) {
- return -1;
- }
- return inner_splice_new_item (parent_node, pos, candidate);
- }
-
- /*
- * Move items within a parent to change their z-order.
- *
- * Set restack to false if several move operations will be executed, which could make
- * later restacking more efficient. Make sure to call recalculate_children_stacking
- * after all operations.
- *
- * prep_for_op is an optional lambda that will get called only if the move ends up
- * in an actual change to the model. it serves as a way to have side-effects that
- * don't trigger on no-ops. For example, only add to the undo stack if a change happens.
- */
- public int move_items (
- int parent_id,
- uint pos,
- uint newpos,
- int length,
- bool restack,
- Utils.TrivialDelegate? prep_for_op = null
- ) {
- if (pos == newpos || length <= 0) {
- return 0;
- }
-
- var parent_node = group_nodes.get (parent_id);
- if (parent_node == null) {
- return -1;
- }
-
- if (pos >= parent_node.children.length || pos + length > parent_node.children.length) {
- return -1;
- }
-
- if (newpos + length > parent_node.children.length) {
- return 0;
- }
-
- if (prep_for_op != null) {
- prep_for_op ();
- }
-
- // convert to rotation parameters
- var f = (int) (uint.min (pos, newpos));
- var m = (int) (newpos > pos ? pos + length : pos);
- var e = (int) (uint.max (pos + length, newpos + length));
-
- Utils.Array.rotate_iarray (ref parent_node.instance.children, f, m, e);
- Utils.Array.rotate_weak_garray (ref parent_node.children, f, m, e);
-
- if (restack) {
- var start = int.min ((int)pos, (int)newpos);
- for (var i = start; i < parent_node.children.length; ++i) {
- unowned var ch = parent_node.children.index (i);
- ch.pos_in_parent = i;
- }
- }
-
- if (parent_node.id != ORIGIN_ID) {
- alert_node_changed (parent_node, Components.Component.Type.COMPILED_GEOMETRY);
- }
-
- return 1;
- }
-
- public static ModelNode? root (ModelNode node) {
- if (node.parent == null) {
- assert (node.id == ORIGIN_ID);
- return node;
- }
-
- if (node.parent.id == ORIGIN_ID) {
- return node;
- }
-
- return root (node.parent);
- }
-
- public static ModelNode? next_sibling (ModelNode node, bool only_stackable) {
- if (node == null || node.parent == null) {
- return null;
- }
-
- var sibling_pos = node.pos_in_parent + 1;
- unowned ModelNode sibling = null;
- while (sibling_pos < node.parent.children.length) {
- sibling = node.parent.children.index (sibling_pos);
- if (!only_stackable || sibling.instance.is_stackable) {
- return sibling;
- }
- sibling_pos++;
- }
-
- return null;
- }
-
- public static ModelNode? previous_sibling (ModelNode node, bool only_stackable) {
- if (node == null || node.parent == null) {
- return null;
- }
-
- var sibling_pos = node.pos_in_parent - 1;
- unowned ModelNode sibling = null;
- while (sibling_pos >= 0) {
- sibling = node.parent.children.index (sibling_pos);
- if (!only_stackable || sibling.instance.is_stackable) {
- return sibling;
- }
- sibling_pos--;
- }
-
- return null;
- }
-
- public void print_instances () {
- print ("Groups: \n");
- foreach (var inst in group_map) {
- print (" >%d -- ", inst.value.id);
-
- if (inst.value.children != null) {
- foreach (var id in inst.value.children) {
- print ("%d ", id);
- }
- }
- print ("\n");
- }
-
- print ("Instances: \n");
- foreach (var inst in item_map) {
- print (" >%d -- \n", inst.value.id);
- }
- }
-
- public void print_dag () {
- print ("DAG: \n");
- print_dag_recurse (group_nodes[ORIGIN_ID], 1);
- }
-
- public void print_dag_recurse (ModelNode node, int level) {
- for (var d = 0; d < level; ++d) {
- print (" ");
- }
-
- print (">%d -- (", node.id);
-
- if (node.parent != null) {
- print ("%d", node.parent.id);
- }
-
- print (")\n");
-
- if (node.children != null) {
- for (var i = 0; i < node.children.length; ++i) {
- print_dag_recurse (node.children.index (i), level + 1);
- }
- }
- }
-
- private int inner_splice_new_item (ModelNode parent_node, uint pos, ModelInstance candidate) {
- var new_id = candidate.is_group ? ++last_group_id : ++last_item_id;
- candidate.id = new_id;
- // Generate the initial name for the item composed by the type name and
- // the id. We subtract the starter IDs from what we show the user just
- // to make it look prettier. The ID saved in the Name component is never
- // used, maybe we could remove it.
- var new_name_id = candidate.is_group ? new_id - GROUP_START_ID : new_id - ITEM_START_ID;
- candidate.components.name = new Lib.Components.Name (
- "%s %i".printf (candidate.type.name_id, new_name_id),
- new_id.to_string ()
- );
- var new_node = new ModelNode (candidate, (int) pos);
-
- if (parent_node.children == null) {
- parent_node.children = new GLib.Array ();
- }
-
- bool update_sibling_locations = false;
- if (pos >= parent_node.children.length) {
- parent_node.children.append_val (new_node);
- Utils.Array.append_to_iarray (ref parent_node.instance.children, new_id);
- } else {
- parent_node.children.insert_val (pos, new_node);
- Utils.Array.insert_at_iarray (ref parent_node.instance.children, (int)pos, new_id);
- update_sibling_locations = true;
- }
-
- if (update_sibling_locations) {
- var ipos = (int) pos;
- for (var i = ipos; i < parent_node.children.length; ++i) {
- parent_node.children.index (ipos).pos_in_parent = ipos++;
- }
- }
-
- if (candidate.is_group) {
- new_node.children = new GLib.Array ();
- }
-
- new_node.parent = parent_node;
-
- add_to_maps (new_node, true);
-
- internal_alert_item_change (new_node, false, Components.Component.Type.COMPILED_GEOMETRY);
-
- return new_id;
- }
-
- private int inner_remove (ModelNode parent_node, ModelNode to_delete, uint pos_in_parent) {
- if (to_delete.children != null) {
- for (var ci = (int) to_delete.children.length - 1; ci >= 0; --ci) {
- unowned var child_node = to_delete.children.index (ci);
- if (child_node.children != null && child_node.children.length > 0) {
- inner_remove (to_delete, child_node, ci);
- continue;
- }
-
- child_node.instance.remove_from_canvas (canvas);
- child_node.parent = null;
- remove_from_maps (child_node.id);
- }
- }
-
- to_delete.instance.remove_from_canvas (canvas);
- to_delete.parent = null;
-
- Utils.Array.remove_from_iarray (ref parent_node.instance.children, (int)pos_in_parent, 1);
- parent_node.children.remove_index (pos_in_parent);
-
- if (parent_node.id != ORIGIN_ID) {
- internal_alert_item_change (parent_node, false, Components.Component.Type.COMPILED_GEOMETRY);
- }
-
- remove_from_maps (to_delete.id);
- return 0;
- }
-
- private void add_to_maps (ModelNode node, bool listen) {
- // TODO create drawable in a nicer way.
- node.instance.add_to_canvas ();
-
- naive_add_to_maps (node);
-
- if (listener != null && listen) {
- listener.on_item_added (node.id);
- }
- }
-
- private void naive_add_to_maps (ModelNode node) {
- if (node.instance.is_group) {
- group_map[node.id] = node.instance;
- group_nodes[node.id] = node;
- } else {
- item_map[node.id] = node.instance;
- item_nodes[node.id] = node;
- }
- }
-
- private void remove_from_maps (int id) {
- var target = instance_from_id (id);
- if (target == null) {
- return;
- }
-
- if (id < ITEM_START_ID) {
- group_nodes.unset (id);
- group_map.unset (id);
- } else {
- item_nodes.unset (id);
- item_map.unset (id);
- }
- }
-
- private void build_path_recursive (ModelNode node, ref StringBuilder builder) {
- if (node.parent != null) {
- build_path_recursive (node.parent, ref builder);
- }
-
- if (builder.len > 0) {
- builder.append ("_");
- }
-
- builder.append ((node.id == ORIGIN_ID) ? node.id.to_string () : node.pos_in_parent.to_string ());
- }
-
- private void build_array_path_recursive (ModelNode node, ref Array path) {
- if (node.parent != null) {
- build_array_path_recursive (node.parent, ref path);
- }
-
- path.append_val (((node.id == ORIGIN_ID) ? node.id : node.pos_in_parent));
- }
-
- /*
- * Internal operation to mark an instance as dirty. If 'simple' is true,
- * only the instance's geometry is nullified, otherwise a recursive dirtying
- * of items occurs.
- */
- private void internal_alert_item_change (
- Lib.Items.ModelNode node,
- bool simple,
- Components.Component.Type aspect
- ) {
- node.instance.compiled_components.clear_component (aspect);
-
- if (!simple) {
- mark_changed (node, aspect);
- }
- }
-
- private void mark_changed (Lib.Items.ModelNode node, Components.Component.Type aspect) {
- if (listener == null) {
- return;
- }
-
- if (node.instance.is_group) {
- changed_groups.add (node.id);
- } else {
- changed_items.add (node.id);
- }
-
- unowned var parent = node.parent;
- while (parent.id != ORIGIN_ID) {
- internal_alert_item_change (parent, true, aspect);
- mark_changed (parent, aspect);
- parent = parent.parent;
- }
- }
-
- private void internal_recalculate_children_stacking (ModelNode parent_node) {
- int ct = 0;
- foreach (unowned var child in parent_node.children.data) {
- child.pos_in_parent = ct++;
- }
- }
-
- private void regenerate_node (ModelNode node) {
- var ct = 0;
-
- foreach (unowned var ch in node.instance.children) {
- var ch_inst = instance_from_id (ch);
- var ch_node = new ModelNode (ch_inst, ct);
- ch_node.parent = node;
-
- if (node.children == null) {
- node.children = new GLib.Array ();
- }
-
- node.children.append_val (ch_node);
-
- naive_add_to_maps (ch_node);
-
- regenerate_node (ch_node);
- ++ct;
- }
-
- if (node.id != ORIGIN_ID) {
- if (node.id < ITEM_START_ID) {
- changed_groups.add (node.id);
- } else {
- changed_items.add (node.id);
- }
-
- node.instance.add_to_canvas ();
- }
- }
-
- private void internal_compile_geometries () {
- if (listener == null) {
- return;
- }
-
- if (changed_items.size == 0 && changed_groups.size == 0) {
- return;
- }
-
- foreach (var leaf in changed_items) {
- var node = node_from_id (leaf);
- if (node.instance.compile_components (node, canvas)) {
- if (listener != null) {
- listener.on_item_geometry_changed (node.id);
- }
- }
- }
-
- changed_items.clear ();
-
- if (changed_groups.size == 0) {
- return;
- }
-
- var sorted = new Gee.TreeMap ();
- foreach (var group_id in changed_groups) {
- var group_node = node_from_id (group_id);
- sorted[path_from_node (group_node)] = group_node;
- }
-
- var it = sorted.bidir_map_iterator ();
- for (var has_next = it.last (); has_next; has_next = it.previous ()) {
- var node = it.get_value ();
- if (node.instance.compile_components (node, canvas)) {
- if (listener != null) {
- listener.on_item_geometry_changed (node.id);
- }
- }
-
- // #TODO improve this
- if (node.instance.components.layout.clips_children) {
- if (node.children == null) {
- continue;
- }
-
- unowned var clip = node.instance.compiled_geometry.area;
- foreach (unowned var child in node.children.data) {
- unowned var dr = child.instance.drawable;
- if (dr != null) {
- dr.clipping_path = clip;
- }
- }
- }
- }
-
- changed_groups.clear ();
- }
-}
diff --git a/src/Lib/Items/ModelInstance.vala b/src/Lib/Items/ModelInstance.vala
deleted file mode 100644
index 9e8fc8829..000000000
--- a/src/Lib/Items/ModelInstance.vala
+++ /dev/null
@@ -1,191 +0,0 @@
-/**
- * Copyright (c) 2019-2021 Alecaddd (https://alecaddd.com)
- *
- * This file is part of Akira.
- *
- * Akira 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.
-
- * Akira 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 Akira. If not, see .
- *
- * Authored by: Martin "mbfraga" Fraga
- */
-
-/*
- * An instance represents a single item. It contains information needed to represent and handle
- * an item in the model. If it is a group, it may have children.
- *
- * Instances can live in a model or be freestanding.
- * - Freestanding instances are generally clones of other instances used for caching or copying
- * - Instances in a model are part of the scene and get an associated ModelNode within the Model.
- * If there are children, then the corresponding ModelNode will have those children as nodes.
- * There is obviously no trivial way to get a child instance without its parent model.
- *
- * Components are clonable collection of immutable bits of information about an instance, they
- * are used to generate the scene or dictate behavior specific to an instance. In general,
- * components are aspects of an instance that make sense being serialized / deserialized. If this
- * is not the case for a specific bit of information (e.g., a volatile aspect like selection state),
- * then that bit of information should NOT be a component
- * Components should never depend on other nodes in the model.
- *
- * CompiledComponents are generated at model compilation from other components. They are volatile
- * and do NOT get serialized / deserialized. They are always reconstructible from the original
- * Components. For example, the bounding box of a component depends on it size, transformation, etc;
- * so it is a compiled component.
- * Compiled Components can depend on other nodes in the model.
- * Freestanding items generally don't have or need compiled components.
- *
- * Some data is cached in the instance to make some calculations faster. This includes the actual
- * drawable object and the boundingboxes calculated after compilation.
- *
- * Caching an instance is ok. HOWEVER, when modifying an instance, make sure to use the id
- * and query it back from the Model. Instances can get replaced or deleted without warning,
- * so it is vital to make sure that modifications occur directly on the model. This should
- * not be a performance concern in the vast majority of cases.
- */
-public class Akira.Lib.Items.ModelInstance {
- public int id;
- public int[] children;
-
- public ModelType type = null;
-
- public Lib.Components.Components components;
- public Lib.Components.CompiledComponents compiled_components;
-
- public Drawables.Drawable drawable = null;
- public Geometry.Rectangle bounding_box;
- public Geometry.Rectangle drawable_bounding_box;
-
- public Components.CompiledGeometry compiled_geometry { get { return compiled_components.compiled_geometry; } }
- public Components.CompiledFill compiled_fill { get { return compiled_components.compiled_fill; } }
- public Components.CompiledBorder compiled_border { get { return compiled_components.compiled_border; } }
- public Components.CompiledName compiled_name { get { return compiled_components.compiled_name; } }
-
- public bool is_group { get { return type.is_group (); } }
- public bool is_artboard { get { return type.is_artboard (); } }
- public bool is_stackable { get { return drawable != null; } }
-
- public ModelInstance (int uid, ModelType type) {
- this.type = type;
- components = Lib.Components.Components ();
- compiled_components = Lib.Components.CompiledComponents ();
- bounding_box = Geometry.Rectangle ();
- drawable_bounding_box = Geometry.Rectangle ();
-
- if (is_group) {
- this.children = new int[0];
- }
-
- this.id = uid;
- }
-
- public ModelInstance clone (bool full = false) {
- var cln = new ModelInstance (full ? id : -1, type);
- cln.components = components;
-
- if (full) {
- cln.children = children;
- // TODO eventually this should be cachable--for now they break everything.
- //cln.compiled_components = compiled_components;
- //cln.drawable = drawable;
- //cln.bounding_box = bounding_box;
- //cln.drawable_bounding_box = drawable_bounding_box;
- }
-
- return cln;
- }
-
- /*
- * Creates a dummy item -- useful for unit testing
- */
- public static ModelInstance dummy_item () {
- return new ModelInstance (-1, new DummyItemType ());
- }
-
- /*
- * Creates a dummy group -- useful for unit testing
- */
- public static ModelInstance dummy_group () {
- return new ModelInstance (-1, new DummyGroupType ());
- }
-
-
- /*
- * Compiles the component for this item. If a corresponding node is passed, that node
- * is used in the compilation process.
- * This should almost always be called by the model--unless you really know what you are doing.
- * If in doubt, you don't.
- */
- public bool compile_components (ModelNode node, ViewLayers.BaseCanvas? canvas) {
- bool something_changed = false;
- something_changed = compiled_components.maybe_compile_fill (type, components, node) || something_changed;
- something_changed = compiled_components.maybe_compile_border (type, components, node) || something_changed;
- something_changed = compiled_components.maybe_compile_geometry (type, components, node) || something_changed;
- something_changed = node.instance.is_artboard
- && compiled_components.maybe_compile_name (type, components, node)
- || something_changed;
-
- notify_view_of_changes ();
-
- if (something_changed) {
- update_drawable_bounds (canvas);
- }
-
- return something_changed;
- }
-
- public void notify_view_of_changes () {
- if (compiled_components.is_empty) {
- return;
- }
-
- if (drawable == null) {
- return;
- }
-
- var dirty_types = compiled_components.dirty_components.types;
- for (var i = 0; i < dirty_types.length; ++i) {
- var dirty_type = dirty_types[i];
- if (dirty_type.dirty) {
- type.component_updated (this, dirty_type.type);
- }
-
- compiled_components.dirty_components.mark_dirty (dirty_type.type, false);
- }
- }
-
- public void add_to_canvas () {
- type.construct_canvas_item (this);
- }
-
- public void remove_from_canvas (ViewLayers.BaseCanvas? canvas) {
- // A ModelTypeGroup doesn't have a drawable instance.
- if (canvas != null && drawable != null) {
- drawable.request_redraw (canvas, false);
- }
- drawable = null;
- }
-
- private void update_drawable_bounds (ViewLayers.BaseCanvas? canvas) {
- bounding_box = compiled_geometry.area_bb;
- if (drawable != null) {
- if (canvas != null) {
- drawable.request_redraw (canvas, false);
- drawable.bounds = compiled_geometry.drawable_bb;
- drawable.request_redraw (canvas, false);
- drawable_bounding_box = drawable.bounds;
- return;
- }
- }
-
- drawable_bounding_box = bounding_box;
- }
-}
diff --git a/src/Lib/Items/ModelNode.vala b/src/Lib/Items/ModelNode.vala
deleted file mode 100644
index ffd275f0f..000000000
--- a/src/Lib/Items/ModelNode.vala
+++ /dev/null
@@ -1,206 +0,0 @@
-/**
- * Copyright (c) 2019-2021 Alecaddd (https://alecaddd.com)
- *
- * This file is part of Akira.
- *
- * Akira 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.
-
- * Akira 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 Akira. If not, see .
- *
- * Authored by: Martin "mbfraga" Fraga
- */
-
-/*
- * ModelNode is a DAG representation of the model. It populates the information of an ModelInstance
- * that lives within a Model. This information includes its parent's ModelNode, its children
- * ModelNodes (may be empty) and the original instance.
- *
- * The main purpose of a ModelNode is to ease traversal of the Model without n lookups. It should
- * NOT be cached. There are few exceptions for performance, and when done, it is very important
- * that the lifetime of the container of that cache gets notified whenever a node is destructed.
- * This should very rarely be needed.
- *
- * It is recommended that nodes should be queried on demand from a model whenever needed.
- */
-public class Akira.Lib.Items.ModelNode {
- public int id;
- // This is the position of the node relative to its parent.
- public int pos_in_parent = -1;
- public unowned ModelInstance instance;
-
- public unowned ModelNode parent = null;
- public GLib.Array children;
-
- public ModelNode (ModelInstance instance, int pos_in_parent) {
- this.instance = instance;
- this.id = instance.id;
- this.pos_in_parent = pos_in_parent;
- }
-
- public void swap_children (int pos, int newpos) {
- var tmp = children.data[pos];
- children.data[pos] = children.data[newpos];
- children.data[newpos] = tmp;
- }
-
- public bool has_child (int id, bool recurse = true) {
- if (children == null) {
- return false;
- }
-
- foreach (var child in children.data) {
- if (child.id == id) {
- return true;
- }
-
- if (recurse && child.instance.is_group) {
- if (child.has_child (id)) {
- return true;
- }
- }
- }
-
- return false;
- }
-
- /*
- * Return an array of int containing all IDs of the children of this node.
- */
- public int[] get_children_ids () {
- Array children_ids = new Array ();
-
- if (children == null) {
- return children_ids.data;
- }
-
- foreach (var child in children.data) {
- children_ids.append_val (child.id);
- get_children_ids_recursive (child, ref children_ids);
- }
-
- return children_ids.data;
- }
-
- private void get_children_ids_recursive (ModelNode node, ref Array children_ids) {
- if (node.children == null) {
- return;
- }
-
- foreach (var child in node.children.data) {
- children_ids.append_val (child.id);
- get_children_ids_recursive (child, ref children_ids);
- }
- }
-
- public bool has_ancestor (int id, bool recurse = true) {
- var p = parent;
-
- while (p != null) {
- if (p.id == id) {
- return true;
- }
- p = p.parent;
- }
-
- return false;
- }
-
- /*
- * Get the number of ancestors the current model belongs to.
- */
- public int get_ancestors_size () {
- // Start with a negative value since all items have a parent, which is
- // the main canvas, and we want to ignore that.
- int n = -1;
- var p = parent;
-
- while (p != null) {
- n++;
- p = p.parent;
- }
-
- return n;
- }
-
- /*
- * Get the transform that maps this node's geometry to the world
- */
- public Cairo.Matrix get_ancestor_transform () {
- var result = Cairo.Matrix.identity ();
- ModelNode? parent = parent;
- while (parent != null && parent.id != Model.ORIGIN_ID) {
- unowned var geom = parent.instance.compiled_geometry;
- if (geom != null) {
- var tmp = geom.transformation_matrix;
- result.multiply (tmp, result);
- }
- parent = parent.parent;
- }
- return result;
- }
-
- public void items_in_canvas (
- double x,
- double y,
- Cairo.Context cr,
- double scale,
- Drawables.Drawable.HitTestType hit_test_type,
- ref Gee.ArrayList nodes
- ) {
- if (instance.components.layer.locked) {
- return;
- }
-
- unowned var dr = instance.drawable;
- if (dr == null || (instance.is_group && !instance.is_artboard)) {
- if (!instance.bounding_box.contains (x, y)) {
- return;
- }
- } else {
- if (dr.hit_test (x, y, cr, scale, hit_test_type)) {
- nodes.add (this);
- }
- }
-
- if (children != null) {
- foreach (unowned var child in children.data) {
- child.items_in_canvas (x, y, cr, scale, hit_test_type, ref nodes);
- }
- }
- }
-}
-
-public class Akira.Lib.Items.PositionKey {
- public string parent_path;
- public int pos_in_parent;
-
- public static int compare (PositionKey a, PositionKey b) {
- if (a.parent_path == b.parent_path) {
- if (a.pos_in_parent == b.pos_in_parent) {
- return 0;
- }
-
- return a.pos_in_parent < b.pos_in_parent ? -1 : 1;
- }
-
- return a.parent_path < b.parent_path ? -1 : 1;
- }
-}
-
-public class Akira.Lib.Items.ChildrenSet {
- public ModelNode parent_node;
- public int first_child;
- public int length;
-
- // optional array with children nodes
- public GLib.Array children_in_set;
-}
diff --git a/src/Lib/Items/ModelType.vala b/src/Lib/Items/ModelType.vala
deleted file mode 100644
index 74817b8ef..000000000
--- a/src/Lib/Items/ModelType.vala
+++ /dev/null
@@ -1,90 +0,0 @@
-/**
- * Copyright (c) 2019-2021 Alecaddd (https://alecaddd.com)
- *
- * This file is part of Akira.
- *
- * Akira 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.
-
- * Akira 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 Akira. If not, see .
- *
- * Authored by: Martin "mbfraga" Fraga
- */
-
-public class Akira.Lib.Items.ModelType : Object {
- public virtual string name_id { get { return "empty"; } }
-
- public virtual Components.CompiledFill compile_fill (
- Components.Components? components,
- Lib.Items.ModelNode? node
- ) {
- return Components.CompiledFill.compile (components, node);
- }
-
- public virtual Components.CompiledBorder compile_border (
- Components.Components? components,
- Lib.Items.ModelNode? node
- ) {
- return Components.CompiledBorder.compile (components, node);
- }
-
- public virtual Components.CompiledGeometry compile_geometry (
- Components.Components? components,
- Lib.Items.ModelNode? node
- ) {
- return new Components.CompiledGeometry.from_components (components, node);
- }
-
- public virtual Components.CompiledName compile_name (
- Components.Components? components,
- Lib.Items.ModelNode? node
- ) {
- return new Components.CompiledName (components.name.name);
- }
-
- public virtual void construct_canvas_item (ModelInstance item) {}
-
- public virtual void component_updated (ModelInstance item, Lib.Components.Component.Type type) {}
-
- public virtual void apply_scale_transform (
- Lib.Items.Model item_model,
- Lib.Items.ModelNode node,
- Lib.Modes.TransformMode.InitialDragState initial_drag_state,
- Cairo.Matrix inverse_reference_matrix,
- double global_offset_x,
- double global_offset_y,
- double reference_sx,
- double reference_sy
- ) {
- Utils.AffineTransform.scale_node (
- item_model,
- node,
- initial_drag_state,
- inverse_reference_matrix,
- global_offset_x,
- global_offset_y,
- reference_sx,
- reference_sy
- );
- }
-
- public virtual bool is_group () { return false; }
- public virtual bool is_artboard () { return false; }
-}
-
-public class Akira.Lib.Items.DummyItemType : ModelType {
- public override string name_id { get { return "dummy_item"; } }
-}
-
-public class Akira.Lib.Items.DummyGroupType : ModelType {
- public override string name_id { get { return "dummy_group"; } }
- public override bool is_group () { return true; }
-}
diff --git a/src/Lib/Items/ModelTypeArtboard.vala b/src/Lib/Items/ModelTypeArtboard.vala
deleted file mode 100644
index 7d7fc6ea2..000000000
--- a/src/Lib/Items/ModelTypeArtboard.vala
+++ /dev/null
@@ -1,86 +0,0 @@
-/**
- * Copyright (c) 2019-2021 Alecaddd (https://alecaddd.com)
- *
- * This file is part of Akira.
- *
- * Akira 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.
-
- * Akira 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 Akira. If not, see .
- *
- * Authored by: Martin "mbfraga" Fraga
- */
-
-public class Akira.Lib.Items.ModelTypeArtboard : ModelType {
-
- public static ModelInstance default_artboard (
- Lib.Components.Coordinates center,
- Lib.Components.Size size
- ) {
- var new_item = new ModelInstance (-1, new ModelTypeArtboard ());
- new_item.components.center = center;
- new_item.components.size = size;
- new_item.components.transform = Lib.Components.Components.default_transform ();
- new_item.components.flipped = Lib.Components.Components.default_flipped ();
-
- new_item.components.fills = new Lib.Components.Fills.with_color (Lib.Components.Color (1.0, 1.0, 1.0, 1.0));
-
- var layout_data = Components.Layout.LayoutData () {
- can_rotate = true,
- dilated_resize = false,
- clips_children = true
- };
- new_item.components.layout = new Components.Layout (layout_data);
- new_item.components.name = Lib.Components.Components.default_name ();
- new_item.components.layer = Lib.Components.Components.default_layer ();
- return new_item;
- }
-
- public override string name_id { get { return "artboard"; } }
-
- public override void construct_canvas_item (ModelInstance instance) {
- var w = instance.components.size.width;
- var h = instance.components.size.height;
- instance.drawable = new Drawables.DrawableArtboard (
- - (w / 2.0),
- - (h / 2.0),
- w,
- h
- );
- }
-
- public override void component_updated (ModelInstance instance, Lib.Components.Component.Type type) {
- switch (type) {
- case Lib.Components.Component.Type.COMPILED_FILL:
- if (!instance.compiled_fill.is_visible) {
- instance.drawable.fill_rgba = Gdk.RGBA () { alpha = 0 };
- break;
- }
-
- instance.drawable.fill_rgba = instance.compiled_fill.color;
- break;
- case Lib.Components.Component.Type.COMPILED_GEOMETRY:
- instance.drawable.width = instance.components.size.width;
- instance.drawable.height = instance.components.size.height;
- instance.drawable.transform = instance.compiled_geometry.transformation_matrix;
- break;
- case Lib.Components.Component.Type.COMPILED_NAME:
- instance.drawable.label = instance.compiled_name.name;
- break;
- case Lib.Components.Component.Type.COMPILED_BORDER:
- // Artboards can't have borders, so don't do anything.
- break;
- }
- }
-
- public override bool is_group () { return true; }
- public override bool is_artboard () { return true; }
-}
diff --git a/src/Lib/Items/ModelTypeEllipse.vala b/src/Lib/Items/ModelTypeEllipse.vala
deleted file mode 100644
index 9e47d71e9..000000000
--- a/src/Lib/Items/ModelTypeEllipse.vala
+++ /dev/null
@@ -1,91 +0,0 @@
-/**
- * Copyright (c) 2019-2021 Alecaddd (https://alecaddd.com)
- *
- * This file is part of Akira.
- *
- * Akira 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.
-
- * Akira 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 Akira. If not, see .
- *
- * Authored by: Martin "mbfraga" Fraga
- */
-
-public class Akira.Lib.Items.ModelTypeEllipse : ModelType {
- public static ModelInstance minimal_ellipse () {
- return default_ellipse (
- new Lib.Components.Coordinates (0.5, 0.5),
- new Lib.Components.Size (1, 1, false),
- null,
- null
- );
- }
-
- public static ModelInstance default_ellipse (
- Lib.Components.Coordinates center,
- Lib.Components.Size size,
- Lib.Components.Borders? borders,
- Lib.Components.Fills? fills
- ) {
- var new_item = new ModelInstance (-1, new ModelTypeEllipse ());
- new_item.components.center = center;
- new_item.components.size = size;
- new_item.components.borders = borders;
- new_item.components.fills = fills;
- new_item.components.transform = Lib.Components.Components.default_transform ();
- new_item.components.flipped = Lib.Components.Components.default_flipped ();
- new_item.components.border_radius = Lib.Components.Components.default_border_radius ();
- new_item.components.name = Lib.Components.Components.default_name ();
- new_item.components.layer = Lib.Components.Components.default_layer ();
- return new_item;
- }
-
- public override string name_id { get { return "ellipse"; } }
-
- public override void construct_canvas_item (ModelInstance instance) {
- var radius_x = instance.components.size.width / 2.0;
- var radius_y = instance.components.size.height / 2.0;
- instance.drawable = new Drawables.DrawableEllipse (0, 0, radius_x, radius_y);
- }
-
- public override void component_updated (ModelInstance instance, Lib.Components.Component.Type type) {
- switch (type) {
- case Lib.Components.Component.Type.COMPILED_BORDER:
- if (!instance.compiled_border.is_visible) {
- instance.drawable.line_width = 0;
- instance.drawable.stroke_rgba = Gdk.RGBA () { alpha = 0 };
- break;
- }
-
- // The "line-width" property expects a DOUBLE type, but we don't support subpixels
- // so we always handle the border size as INT, therefore we need to type cast it here.
- instance.drawable.line_width = (double) instance.compiled_border.size;
- instance.drawable.stroke_rgba = instance.compiled_border.color;
- break;
- case Lib.Components.Component.Type.COMPILED_FILL:
- if (!instance.compiled_fill.is_visible) {
- instance.drawable.fill_rgba = Gdk.RGBA () { alpha = 0 };
- break;
- }
-
- instance.drawable.fill_rgba = instance.compiled_fill.color;
- break;
- case Lib.Components.Component.Type.COMPILED_GEOMETRY:
- var ellipse = instance.drawable as Drawables.DrawableEllipse;
- ellipse.radius_x = instance.components.size.width / 2.0;
- ellipse.radius_y = instance.components.size.height / 2.0;
- instance.drawable.transform = instance.compiled_geometry.transformation_matrix;
- break;
- default:
- break;
- }
- }
-}
diff --git a/src/Lib/Items/ModelTypeGroup.vala b/src/Lib/Items/ModelTypeGroup.vala
deleted file mode 100644
index fadac8788..000000000
--- a/src/Lib/Items/ModelTypeGroup.vala
+++ /dev/null
@@ -1,50 +0,0 @@
-/**
- * Copyright (c) 2019-2021 Alecaddd (https://alecaddd.com)
- *
- * This file is part of Akira.
- *
- * Akira 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.
-
- * Akira 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 Akira. If not, see .
- *
- * Authored by: Martin "mbfraga" Fraga
- */
-
-public class Akira.Lib.Items.ModelTypeGroup : ModelType {
- public static ModelInstance default_group () {
- var new_item = new ModelInstance (-1, new ModelTypeGroup ());
- var layout_data = Components.Layout.LayoutData () {
- can_rotate = true,
- dilated_resize = true,
- clips_children = false
- };
- new_item.components.layout = new Components.Layout (layout_data);
- new_item.components.name = Lib.Components.Components.default_name ();
- new_item.components.layer = Lib.Components.Components.default_layer ();
- return new_item;
- }
-
- public override string name_id { get { return "group"; } }
-
- public override Components.CompiledGeometry compile_geometry (
- Components.Components? components,
- Lib.Items.ModelNode? node
- ) {
- return new Components.CompiledGeometry.from_descendants (components, node);
- }
-
- public override void construct_canvas_item (ModelInstance instance) {
- instance.drawable = new Drawables.DrawableGroup ();
- }
-
- public override bool is_group () { return true; }
-}
diff --git a/src/Lib/Items/ModelTypePath.vala b/src/Lib/Items/ModelTypePath.vala
deleted file mode 100644
index 532e711c7..000000000
--- a/src/Lib/Items/ModelTypePath.vala
+++ /dev/null
@@ -1,104 +0,0 @@
-/**
- * Copyright (c) 2019-2021 Alecaddd (https://alecaddd.com)
- *
- * This file is part of Akira.
- *
- * Akira 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.
-
- * Akira 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 Akira. If not, see .
- *
- * Authored by: Martin "mbfraga" Fraga
- */
-
-public class Akira.Lib.Items.ModelTypePath : ModelType {
- public static ModelInstance minimal_rect () {
- return default_path (
- new Lib.Components.Coordinates (0.5, 0.5),
- null,
- null
- );
- }
-
- public static ModelInstance default_path (
- Lib.Components.Coordinates center,
- Lib.Components.Borders? borders,
- Lib.Components.Fills? fills
- ) {
- var new_item = new ModelInstance (-1, new ModelTypePath ());
- new_item.components.center = center;
- new_item.components.borders = borders;
- new_item.components.fills = fills;
- new_item.components.transform = Lib.Components.Components.default_transform ();
- new_item.components.flipped = Lib.Components.Components.default_flipped ();
- new_item.components.border_radius = Lib.Components.Components.default_border_radius ();
- new_item.components.path = new Lib.Components.Path.from_single_point (
- Akira.Geometry.Point (center.x, center.y),
- false
- );
- new_item.components.size = new Lib.Components.Size (1, 1, false);
- new_item.components.name = Lib.Components.Components.default_name ();
- new_item.components.layer = Lib.Components.Components.default_layer ();
- return new_item;
- }
-
- public override string name_id { get { return "path"; } }
-
- public override Components.CompiledGeometry compile_geometry (
- Components.Components? components,
- Lib.Items.ModelNode? node
- ) {
- return new Components.CompiledGeometry.from_components (components, node, true);
- }
-
- public override void construct_canvas_item (ModelInstance instance) {
- instance.drawable = new Drawables.DrawablePath (
- (instance.components.path == null) ? null : instance.components.path.data
- );
- }
-
- public override void component_updated (ModelInstance instance, Lib.Components.Component.Type type) {
- switch (type) {
- case Lib.Components.Component.Type.COMPILED_BORDER:
- if (!instance.compiled_border.is_visible) {
- instance.drawable.line_width = 0;
- instance.drawable.stroke_rgba = Gdk.RGBA () { alpha = 0 };
- break;
- }
-
- // The "line-width" property expects a DOUBLE type, but we don't support subpixels
- // so we always handle the border size as INT, therefore we need to type cast it here.
- instance.drawable.line_width = (double) instance.compiled_border.size;
- instance.drawable.stroke_rgba = instance.compiled_border.color;
- break;
- case Lib.Components.Component.Type.COMPILED_FILL:
- if (!instance.compiled_fill.is_visible) {
- instance.drawable.fill_rgba = Gdk.RGBA () { alpha = 0 };
- break;
- }
-
- instance.drawable.fill_rgba = instance.compiled_fill.color;
- break;
- case Lib.Components.Component.Type.COMPILED_GEOMETRY:
- // The points property is only available to DrawablePath, so first typecast it
- // modify it, then assign to instance.
- Drawables.DrawablePath drawable = instance.drawable as Drawables.DrawablePath;
- drawable.center_x = -instance.compiled_geometry.source_width / 2.0;
- drawable.center_y = -instance.compiled_geometry.source_height / 2.0;
- drawable.transform = instance.compiled_geometry.transformation_matrix;
- drawable.points = instance.components.path.data;
- drawable.close = instance.components.path.close;
- break;
- default:
- break;
- }
- }
-}
diff --git a/src/Lib/Items/ModelTypeRect.vala b/src/Lib/Items/ModelTypeRect.vala
deleted file mode 100644
index c09384526..000000000
--- a/src/Lib/Items/ModelTypeRect.vala
+++ /dev/null
@@ -1,95 +0,0 @@
-/**
- * Copyright (c) 2019-2021 Alecaddd (https://alecaddd.com)
- *
- * This file is part of Akira.
- *
- * Akira 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.
-
- * Akira 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 Akira. If not, see .
- *
- * Authored by: Martin "mbfraga" Fraga
- */
-
-public class Akira.Lib.Items.ModelTypeRect : ModelType {
- public static ModelInstance minimal_rect () {
- return default_rect (
- new Lib.Components.Coordinates (0.5, 0.5),
- new Lib.Components.Size (1, 1, false),
- null,
- null
- );
- }
-
- public static ModelInstance default_rect (
- Lib.Components.Coordinates center,
- Lib.Components.Size size,
- Lib.Components.Borders? borders,
- Lib.Components.Fills? fills
- ) {
- var new_item = new ModelInstance (-1, new ModelTypeRect ());
- new_item.components.center = center;
- new_item.components.size = size;
- new_item.components.borders = borders;
- new_item.components.fills = fills;
- new_item.components.transform = Lib.Components.Components.default_transform ();
- new_item.components.flipped = Lib.Components.Components.default_flipped ();
- new_item.components.border_radius = Lib.Components.Components.default_border_radius ();
- new_item.components.name = Lib.Components.Components.default_name ();
- new_item.components.layer = Lib.Components.Components.default_layer ();
- return new_item;
- }
-
- public override string name_id { get { return "rectangle"; } }
-
- public override void construct_canvas_item (ModelInstance instance) {
- var w = instance.components.size.width;
- var h = instance.components.size.height;
- instance.drawable = new Drawables.DrawableRect (
- - (w / 2.0),
- - (h / 2.0),
- w,
- h
- );
- }
-
- public override void component_updated (ModelInstance instance, Lib.Components.Component.Type type) {
- switch (type) {
- case Lib.Components.Component.Type.COMPILED_BORDER:
- if (!instance.compiled_border.is_visible) {
- instance.drawable.line_width = 0;
- instance.drawable.stroke_rgba = Gdk.RGBA () { alpha = 0 };
- break;
- }
-
- // The "line-width" property expects a DOUBLE type, but we don't support subpixels
- // so we always handle the border size as INT, therefore we need to type cast it here.
- instance.drawable.line_width = (double) instance.compiled_border.size;
- instance.drawable.stroke_rgba = instance.compiled_border.color;
- break;
- case Lib.Components.Component.Type.COMPILED_FILL:
- if (!instance.compiled_fill.is_visible) {
- instance.drawable.fill_rgba = Gdk.RGBA () { alpha = 0 };
- break;
- }
-
- instance.drawable.fill_rgba = instance.compiled_fill.color;
- break;
- case Lib.Components.Component.Type.COMPILED_GEOMETRY:
- instance.drawable.width = instance.components.size.width;
- instance.drawable.height = instance.components.size.height;
- instance.drawable.transform = instance.compiled_geometry.transformation_matrix;
- break;
- default:
- break;
- }
- }
-}
diff --git a/src/Lib/Items/ModelTypeText.vala b/src/Lib/Items/ModelTypeText.vala
deleted file mode 100644
index 445039acd..000000000
--- a/src/Lib/Items/ModelTypeText.vala
+++ /dev/null
@@ -1,94 +0,0 @@
-/**
- * Copyright (c) 2019-2021 Alecaddd (https://alecaddd.com)
- *
- * This file is part of Akira.
- *
- * Akira 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.
-
- * Akira 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 Akira. If not, see .
- *
- * Authored by: Martin "mbfraga" Fraga
- */
-
-public class Akira.Lib.Items.ModelTypeText : ModelType {
- public static ModelInstance minimal_text () {
- return default_text (
- new Lib.Components.Coordinates (0.5, 0.5),
- new Lib.Components.Size (1, 1, false),
- new Lib.Components.Text ("Akira")
- );
- }
-
- public static ModelInstance default_text (
- Lib.Components.Coordinates center,
- Lib.Components.Size size,
- Lib.Components.Text text
- ) {
- var new_item = new ModelInstance (-1, new ModelTypeText ());
- new_item.components.center = center;
- new_item.components.size = size;
- new_item.components.text = text;
- new_item.components.transform = Lib.Components.Components.default_transform ();
- new_item.components.flipped = Lib.Components.Components.default_flipped ();
- new_item.components.border_radius = Lib.Components.Components.default_border_radius ();
- new_item.components.name = Lib.Components.Components.default_name ();
- new_item.components.layer = Lib.Components.Components.default_layer ();
- return new_item;
- }
-
- public override string name_id { get { return "text"; } }
-
- public override void construct_canvas_item (ModelInstance instance) {
- var w = instance.components.size.width;
- var h = instance.components.size.height;
- string text = (instance.components.text == null) ? "" : instance.components.text.text;
- instance.drawable = new Drawables.DrawableText (
- - (w / 2.0),
- - (h / 2.0),
- w,
- h,
- text
- );
- }
-
- public override void component_updated (ModelInstance instance, Lib.Components.Component.Type type) {
- switch (type) {
- case Lib.Components.Component.Type.COMPILED_BORDER:
- if (!instance.compiled_border.is_visible) {
- instance.drawable.line_width = 0;
- instance.drawable.stroke_rgba = Gdk.RGBA () { alpha = 0 };
- break;
- }
-
- // The "line-width" property expects a DOUBLE type, but we don't support subpixels
- // so we always handle the border size as INT, therefore we need to type cast it here.
- instance.drawable.line_width = (double) instance.compiled_border.size;
- instance.drawable.stroke_rgba = instance.compiled_border.color;
- break;
- case Lib.Components.Component.Type.COMPILED_FILL:
- if (!instance.compiled_fill.is_visible) {
- instance.drawable.fill_rgba = Gdk.RGBA () { alpha = 0 };
- break;
- }
-
- instance.drawable.fill_rgba = instance.compiled_fill.color;
- break;
- case Lib.Components.Component.Type.COMPILED_GEOMETRY:
- instance.drawable.width = instance.components.size.width;
- instance.drawable.height = instance.components.size.height;
- instance.drawable.transform = instance.compiled_geometry.transformation_matrix;
- break;
- default:
- break;
- }
- }
-}
diff --git a/src/Lib/Managers/CopyManager.vala b/src/Lib/Managers/CopyManager.vala
deleted file mode 100644
index 632404a32..000000000
--- a/src/Lib/Managers/CopyManager.vala
+++ /dev/null
@@ -1,182 +0,0 @@
-/**
- * Copyright (c) 2019-2021 Alecaddd (https://alecaddd.com)
- *
- * This file is part of Akira.
- *
- * Akira 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.
-
- * Akira 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 Akira. If not, see .
- *
- * Authored by: Martin "mbfraga" Fraga
- */
-
-public class Akira.Lib.Managers.CopyManager : Object {
- public unowned ViewCanvas view_canvas { get; construct; }
-
- private Lib.Items.Model copy_model;
-
- public CopyManager (ViewCanvas canvas) {
- Object (view_canvas : canvas);
- }
-
- construct {
- view_canvas.window.event_bus.request_copy.connect (do_copy);
- view_canvas.window.event_bus.request_paste.connect (do_paste);
- view_canvas.window.event_bus.request_duplicate.connect (do_duplicate);
- }
-
- /*
- * Return a tree map of the currently selected items, with their sorted position.
- */
- public Gee.TreeMap collect_sorted_candidates () {
- var candidates = new Gee.TreeMap (Lib.Items.PositionKey.compare);
- foreach (var to_copy in view_canvas.selection_manager.selection.nodes.values) {
- var key = new Lib.Items.PositionKey ();
- key.parent_path = view_canvas.items_manager.item_model.path_from_node (to_copy.node.parent);
- key.pos_in_parent = to_copy.node.pos_in_parent;
- candidates[key] = to_copy.node.id;
- }
-
- return candidates;
- }
-
- /*
- * Copy the currently selected nodes.
- */
- public void do_copy () {
- var sorted_candidates = collect_sorted_candidates ();
- // Don't do anything if we don't have selected nodes.
- if (sorted_candidates.size == 0) {
- return;
- }
-
- // Create a new Model to hold all the cloned nodes in memory.
- copy_model = new Lib.Items.Model ();
-
- // Populate the model with all the currently selected nodes.
- int res = 0;
- foreach (var sorted_id in sorted_candidates.values) {
- res += Utils.ModelUtil.clone_from_model (
- view_canvas.items_manager.item_model,
- sorted_id,
- copy_model,
- Lib.Items.Model.ORIGIN_ID
- );
- }
-
- assert (res == 0);
- }
-
- /*
- * Paste a copied node into the item_model.
- * TODO:
- * - If the `in_place` is true, the cloned node should be spliced at the same position of the
- * currently selected node, ignoring the source node position (eg. paste into group, paste into
- * another artboard, etc.), and the X & Y coordinates of the cloned node should match the
- * coordiante sof the currently selected node.
- * - If the `in_place` is false, we should paste the node at the center of the viewport, at the
- * top most position.
- */
- public void do_paste (bool in_place = false) {
- if (copy_model == null) {
- return;
- }
-
- var children = copy_model.node_from_id (Lib.Items.Model.ORIGIN_ID).children;
- if (children == null || children.length == 0) {
- return;
- }
-
- var blocker = new SelectionManager.ChangeSignalBlocker (view_canvas.selection_manager);
- (blocker);
-
- view_canvas.selection_manager.reset_selection ();
- view_canvas.window.event_bus.create_model_snapshot (
- in_place ? "paste selection in place" : "paste selection");
-
- int res = 0;
- foreach (var child in children.data) {
- res += Utils.ModelUtil.clone_from_model (
- copy_model,
- child.id,
- view_canvas.items_manager.item_model,
- Lib.Items.Model.ORIGIN_ID,
- on_subtree_cloned,
- in_place ? Utils.ModelUtil.State.PASTE_IN_PLACE : Utils.ModelUtil.State.PASTE
- );
- }
- assert (res == 0);
- on_after_paste ();
- }
-
- private void do_duplicate () {
- var sorted_candidates = collect_sorted_candidates ();
- // Don't do anything if we don't have selected nodes.
- if (sorted_candidates.size == 0) {
- return;
- }
-
- // Populate the model with all the currently selected nodes. Use a locally
- // scoped variable to not override the copy_model in order to maintain any
- // existing copied model.
- var duplicate_model = new Lib.Items.Model ();
- int res = 0;
- foreach (var sorted_id in sorted_candidates.values) {
- res += Utils.ModelUtil.clone_from_model (
- view_canvas.items_manager.item_model,
- sorted_id,
- duplicate_model,
- Lib.Items.Model.ORIGIN_ID
- );
- }
- assert (res == 0);
-
- if (duplicate_model == null) {
- return;
- }
-
- var children = duplicate_model.node_from_id (Lib.Items.Model.ORIGIN_ID).children;
- if (children == null || children.length == 0) {
- return;
- }
-
- var blocker = new SelectionManager.ChangeSignalBlocker (view_canvas.selection_manager);
- (blocker);
-
- view_canvas.selection_manager.reset_selection ();
- view_canvas.window.event_bus.create_model_snapshot ("duplicate selection");
-
- res = 0;
- foreach (var child in children.data) {
- res += Utils.ModelUtil.clone_from_model (
- duplicate_model,
- child.id,
- view_canvas.items_manager.item_model,
- Lib.Items.Model.ORIGIN_ID,
- on_subtree_cloned,
- Utils.ModelUtil.State.DUPLICATE
- );
- }
- assert (res == 0);
- on_after_paste ();
- }
-
- private void on_after_paste () {
- view_canvas.items_manager.compile_model ();
- // Regenerate the layers list.
- view_canvas.window.main_window.regenerate_list (true);
- }
-
- private void on_subtree_cloned (int id) {
- view_canvas.selection_manager.add_to_selection (id);
- }
-}
diff --git a/src/Lib/Managers/ExportManager.vala b/src/Lib/Managers/ExportManager.vala
deleted file mode 100644
index e1311c0f6..000000000
--- a/src/Lib/Managers/ExportManager.vala
+++ /dev/null
@@ -1,456 +0,0 @@
-/**
- * Copyright (c) 2022-2023 Alecaddd (https://alecaddd.com)
- *
- * This file is part of Akira.
- *
- * Akira 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.
-
- * Akira 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 Akira. If not, see .
- *
- * Authored by: Alessandro "Alecaddd" Castellani
- */
-
-public class Akira.Lib.Managers.ExportManager : Object {
- public signal void busy (string message);
- public signal void show_preview (Gee.HashMap pixbufs);
- public signal void free ();
- public signal void export_finished (string message);
-
- public enum Type {
- AREA,
- SELECTION,
- ARTBOARD
- }
- private Type export_type;
- private Akira.Geometry.Rectangle area;
-
- public unowned Akira.Lib.ViewCanvas canvas { get; construct; }
-
- private Cairo.Format format;
- private Cairo.ImageSurface? surface = null;
- private Cairo.Context? context = null;
- private Gdk.PixbufLoader loader;
- private Gee.HashMap pixbufs;
-
- private GLib.Cancellable? preview_cancellable;
-
- public ExportManager (Lib.ViewCanvas view_canvas) {
- Object (canvas: view_canvas);
- pixbufs = new Gee.HashMap ();
- }
-
- public async void export_selection () {
- export_type = Type.SELECTION;
- trigger_export_dialog ();
- if (preview_cancellable != null) {
- preview_cancellable.cancel ();
- }
-
- preview_cancellable = new GLib.Cancellable ();
- yield generate_preview (preview_cancellable);
- }
-
- public async void export_area (Geometry.Rectangle bounds) {
- export_type = Type.AREA;
- area = bounds;
- trigger_export_dialog ();
- if (preview_cancellable != null) {
- preview_cancellable.cancel ();
- }
-
- preview_cancellable = new GLib.Cancellable ();
- yield generate_preview (preview_cancellable);
- }
-
- public async void generate_preview (GLib.Cancellable cancellable) {
- busy (_("Generating preview, please wait…"));
-
- yield init_generate_preview (cancellable);
- show_preview (pixbufs);
-
- free ();
- }
-
- private async void init_generate_preview (GLib.Cancellable cancellable) {
- pixbufs.clear ();
-
- if (settings.export_format == "png") {
- format = Cairo.Format.ARGB32;
- } else if (settings.export_format == "jpg") {
- format = Cairo.Format.RGB24;
- }
-
- switch (export_type) {
- case Type.SELECTION:
- yield generate_selection_pixbufs (cancellable);
- break;
- case Type.AREA:
- yield generate_area_pixbuf (cancellable);
- break;
- }
- }
-
- private async void generate_area_pixbuf (GLib.Cancellable cancellable) {
- yield generate_image_surface (area);
- var pixbuf = yield generate_pixbuf (surface);
-
- pixbufs.set (Lib.Items.Model.ORIGIN_ID, pixbuf);
- }
-
- private async void generate_selection_pixbufs (GLib.Cancellable cancellable) {
- // Loop through all items and clone the model.
- unowned var selection = canvas.selection_manager.selection;
- foreach (var node_id in selection.nodes.keys) {
- var node = canvas.items_manager.node_from_id (node_id);
- // Ignore a node if it doesn't exists, it's not attached to the canvas, or
- // it's part of a group or artbaord. TODO: handle groups and artboards.
- if (node == null || node.parent == null || node.parent.id != Lib.Items.Model.ORIGIN_ID) {
- continue;
- }
-
- unowned var inst = node.instance;
-
- // Account for the border size to define the export area.
- double border_size = 0;
- if (inst.components.borders != null) {
- var size = inst.components.borders.get_border_width ();
- // Currently we only support centered border as per SVG specs, but
- // in the future we will support internal and external border types
- // so we will need to account for those.
- border_size = size > 0 ? size / 2 : 0;
- }
-
- var top = inst.bounding_box.top - border_size;
- var bottom = inst.bounding_box.bottom + border_size;
- var left = inst.bounding_box.left - border_size;
- var right = inst.bounding_box.right + border_size;
-
- var bounds = Geometry.Rectangle ();
- bounds.top = top;
- bounds.bottom = bottom;
- bounds.left = left;
- bounds.right = right;
-
- yield generate_image_surface (bounds);
- var pixbuf = yield generate_pixbuf (surface);
-
- pixbufs.set (node_id, pixbuf);
- }
- }
-
- private async void generate_image_surface (Geometry.Rectangle bounds) {
- double width = bounds.width;
- double height = bounds.height;
- scale_surface (ref width, ref height);
-
- // Create the rendered image with Cairo.
- surface = new Cairo.ImageSurface (
- format,
- (int) Math.round (width),
- (int) Math.round (height)
- );
- context = new Cairo.Context (surface);
-
- // Draw a white background if JPG export.
- if (settings.export_format == "jpg" || !settings.export_alpha) {
- context.set_source_rgba (1, 1, 1, 1);
- context.rectangle (
- 0, 0,
- (int) Math.round (width),
- (int) Math.round (height)
- );
- context.fill ();
- }
-
- scale_context (ref context);
- // Move the context to the right coordinates.
- context.translate (-bounds.left, -bounds.top);
- // Render what's currently on the canvas inside those coordinates.
- canvas.draw_model (context, bounds);
- }
-
- /*
- * Scale the cairo surface to match the scaled canvas based on the chosen
- * resolution from the user. This is to guarantee a sharp preview.
- */
- private void scale_surface (ref double width, ref double height) {
- switch (settings.export_scale) {
- case 0:
- width = width / 2;
- height = height / 2;
- break;
-
- case 2:
- width = width * 2;
- height = height * 2;
- break;
-
- case 3:
- width = width * 4;
- height = height * 4;
- break;
-
- default:
- width = width * 1;
- height = height * 1;
- break;
- }
- }
-
- /*
- * Scale the canvas context to match the user's export resolution.
- */
- private void scale_context (ref Cairo.Context context) {
- switch (settings.export_scale) {
- case 0:
- context.scale (0.5, 0.5);
- break;
-
- case 2:
- context.scale (2, 2);
- break;
-
- case 3:
- context.scale (4, 4);
- break;
-
- default:
- context.scale (1, 1);
- break;
- }
- }
-
- /*
- * Generate the pixbufs images on a separate async thread in order to now
- * freeze the UI.
- */
- private async Gdk.Pixbuf generate_pixbuf (Cairo.Surface surface) {
- SourceFunc callback = generate_pixbuf.callback;
-
- var thread = new Thread (null, () => {
- // Create pixbuf from stream.
- try {
- loader = new Gdk.PixbufLoader.with_mime_type ("image/png");
- } catch (Error e) {
- error ("Could not create pixbuf loader: %s", e.message);
- }
-
- surface.write_to_png_stream ((data) => {
- try {
- loader.write ((uint8 []) data);
- } catch (Error e) {
- return Cairo.Status.DEVICE_ERROR;
- }
- return Cairo.Status.SUCCESS;
- });
- var pixbuf = loader.get_pixbuf ();
-
- try {
- loader.close ();
- } catch (Error e) {
- error ("Could not close loader: %s", e.message);
- }
-
- Idle.add ((owned) callback);
- return pixbuf;
- });
-
- yield;
-
- return thread.join ();
- }
-
- private void trigger_export_dialog () {
- // Disable all those accels interfering with regular typing.
- canvas.window.event_bus.disconnect_typing_accel ();
-
- var export_dialog = new Akira.Dialogs.ExportDialog (canvas, this);
- export_dialog.show_all ();
- export_dialog.present ();
-
- // Update the dialog UI based on the stored gsettings options.
- export_dialog.update_format_ui ();
-
- export_dialog.close.connect (() => {
- if (preview_cancellable != null) {
- preview_cancellable.cancel ();
- }
-
- // Store the dialog size into gsettings so users don't get upset.
- int width, height;
- export_dialog.get_size (out width, out height);
- settings.export_width = width;
- settings.export_height = height;
-
- // Enable accels again.
- canvas.window.event_bus.connect_typing_accel ();
- canvas.window.event_bus.set_focus_on_canvas ();
-
- // Clean up.
- pixbufs.clear ();
- context = null;
- surface = null;
- });
- }
-
- public async void export_images (GLib.ListStore list_store) {
- busy (_("Exporting images…"));
-
- bool overwrite_all = false;
- bool skip_all = false;
-
- // Loop through all generated models and handle the save to a file.
- for (int i = 0; i < list_store.get_n_items () ; i++) {
- var model = (Akira.Models.ExportModel) list_store.get_object (i);
- var pixbuf = model.pixbuf;
- var file_name = ("%s/%s.%s").printf (
- settings.export_folder,
- model.filename,
- settings.export_format
- );
-
- // Check for existing files to avoid overwriting them.
- var image_file = File.new_for_path (file_name);
- if (image_file.query_exists ()) {
- // Overwrite them all if the user specified it in the dialog
- // during the first loop.
- if (overwrite_all) {
- yield do_export (pixbuf, file_name);
- continue;
- }
-
- // Skip them all if the user specified it in the dialog
- // during the first loop.
- if (skip_all) {
- free ();
- continue;
- }
-
- // Ask the user what to do.
- var results = confirm_overwrite (file_name);
- switch (results[0]) {
- // Overwrite.
- case 3:
- overwrite_all = results[1] == 1;
- yield do_export (pixbuf, file_name);
- break;
- // Skip.
- case 2:
- skip_all = results[1] == 1;
- free ();
- continue;
- // Cancel.
- case 1:
- default:
- free ();
- return;
- }
- continue;
- }
-
- // This file doesn't exist, just export it.
- yield do_export (pixbuf, file_name);
- }
-
- free ();
- export_finished (_("Export completed!"));
- }
-
- /*
- * Trigger a dialog asking the user how to handle an existing file with
- * the same filename.
- */
- private int[] confirm_overwrite (string file_name) {
- int dont_ask = 0;
- int clicked = 0;
- var dialog = canvas.window.dialogs.message_dialog (
- _("File already exists!"),
- _("The file at this location already exists: %s.").printf (file_name),
- "dialog-question",
- _("Overwrite file"),
- _("Skip file")
- );
-
- // If we're currently exporting more than one image, offer the option
- // to use the chosen action as default in the current export loop.
- if (pixbufs.size > 1) {
- var checkbox = new Gtk.CheckButton.with_label (_("Apply the same action for all other files"));
- dialog.custom_bin.add (checkbox);
- checkbox.toggled.connect (() => {
- dont_ask = checkbox.active ? 1 : 0;
- });
- }
-
- dialog.show_all ();
-
- dialog.response.connect ((id) => {
- switch (id) {
- case Gtk.ResponseType.ACCEPT:
- clicked = 3;
- dialog.destroy ();
- break;
- case 2:
- clicked = 2;
- dialog.destroy ();
- break;
- default:
- clicked = 1;
- dialog.destroy ();
- break;
- }
- });
-
- // Use run() to make the UI busy and freeze the loop until we get a response.
- dialog.run ();
-
- return new int[] {clicked, dont_ask};
- }
-
- /*
- * Handle the actual export inside another async thread to avoid freezing
- * the UI while exporting large images.
- */
- private async void do_export (Gdk.Pixbuf pixbuf, string file_name) {
- SourceFunc callback = do_export.callback;
-
- new Thread (null, () => {
- try {
- if (settings.export_format == "png") {
- pixbuf.save (
- file_name,
- "png",
- "compression",
- settings.export_compression.to_string (),
- null);
- }
-
- if (settings.export_format == "jpg") {
- pixbuf.save (
- file_name,
- "jpeg",
- "quality",
- settings.export_quality.to_string (),
- null);
- }
- } catch (Error e) {
- error ("Unable to export images: %s", e.message);
- }
-
- Idle.add ((owned) callback);
- Thread.exit (null);
-
- return null;
- });
-
- yield;
- }
-}
diff --git a/src/Lib/Managers/HistoryManager.vala b/src/Lib/Managers/HistoryManager.vala
deleted file mode 100644
index 0df910d9b..000000000
--- a/src/Lib/Managers/HistoryManager.vala
+++ /dev/null
@@ -1,94 +0,0 @@
-/**
- * Copyright (c) 2019-2021 Alecaddd (https://alecaddd.com)
- *
- * This file is part of Akira.
- *
- * Akira 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.
-
- * Akira 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 Akira. If not, see .
- *
- * Authored by: Martin "mbfraga" Fraga
- */
-
-/*
- *
- */
-public class Akira.Lib.Managers.HistoryManager : Object {
- public unowned ViewCanvas view_canvas { get; construct; }
-
- public class Snapshot {
- public Snapshot (string description, Lib.Items.Model model) {
- this.description = description;
- this.model = model;
- }
-
- public string description;
- public Lib.Items.Model model;
- }
-
- private Gee.LinkedList undo_stack;
- private Gee.LinkedList redo_stack;
-
-
- public HistoryManager (ViewCanvas canvas) {
- Object (view_canvas : canvas);
- view_canvas.window.event_bus.create_model_snapshot.connect (snapshot);
- view_canvas.window.event_bus.undo.connect (undo);
- view_canvas.window.event_bus.redo.connect (redo);
- }
-
- construct {
- undo_stack = new Gee.LinkedList ();
- redo_stack = new Gee.LinkedList ();
- }
-
- private void snapshot (string description) {
- unowned var im = view_canvas.items_manager;
- var clone = new Lib.Items.Model.clone (im.item_model);
- undo_stack.add (new Snapshot (description, clone));
-
- redo_stack.clear ();
- }
-
- public void undo () {
- apply_snapshot (undo_stack, redo_stack);
- }
-
- public void redo () {
- apply_snapshot (redo_stack, undo_stack);
- }
-
- /*
- * Implementation for undo/redo. Shared since they are symmetric.
- */
- private void apply_snapshot (Gee.LinkedList source, Gee.LinkedList other) {
- if (source.size == 0) {
- return;
- }
-
- unowned var im = view_canvas.items_manager;
- view_canvas.selection_manager.reset_selection ();
- view_canvas.mode_manager.deregister_active_mode ();
- view_canvas.hover_manager.remove_hover_effect ();
-
- var last_stack = source.last ();
- source.remove (last_stack);
- other.add (new Snapshot (last_stack.description, new Lib.Items.Model.clone (im.item_model)));
-
- // replace model
- im.replace_model (last_stack.model);
-
- // Regenerate the layers list.
- view_canvas.window.main_window.regenerate_list ();
- }
-
-}
diff --git a/src/Lib/Managers/HoverManager.vala b/src/Lib/Managers/HoverManager.vala
deleted file mode 100644
index ae7ccd536..000000000
--- a/src/Lib/Managers/HoverManager.vala
+++ /dev/null
@@ -1,103 +0,0 @@
-/**
- * Copyright (c) 2019-2021 Alecaddd (https://alecaddd.com)
- *
- * This file is part of Akira.
- *
- * Akira 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.
-
- * Akira 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 Akira. If not, see .
- *
- * Authored by: Martin "mbfraga" Fraga
- * Authored by: Alessandro "Alecaddd" Castellani
- */
-
-public class Akira.Lib.Managers.HoverManager : Object {
- // Signal used to notify other parts of the UI that the hover effect on a
- // canvas item has changed. This must be used exclusively from the canvas to
- // other items, and not vice-versa. If a UI element has to trigger the hover
- // state of an item (like the layers), a dedicated method should be created
- // that doesn't trigger this signal.
- public signal void hover_changed (int? id);
-
- public unowned ViewCanvas view_canvas { get; construct; }
-
- private int current_hovered_id = -1;
- private ViewLayers.ViewLayerHover hover_layer;
-
- public HoverManager (ViewCanvas canvas) {
- Object (view_canvas : canvas);
- }
-
- construct {
- hover_layer = new ViewLayers.ViewLayerHover ();
- hover_layer.add_to_canvas (ViewLayers.ViewLayer.HOVER_LAYER_ID, view_canvas);
- }
-
- public void on_mouse_over (double event_x, double event_y) {
- var target = view_canvas.items_manager.node_at_canvas_position (
- event_x,
- event_y,
- Drawables.Drawable.HitTestType.SELECT
- );
-
- // Remove the hover effect if no item is hovered.
- // TODO: artboard
- if (target == null) {
- remove_hover_effect ();
- hover_changed (null);
- return;
- }
-
- if (view_canvas.selection_manager.item_selected (target.id)) {
- return;
- }
-
- unowned var sm = view_canvas.selection_manager;
- // Account for groups.
- sm.ensure_correct_target (ref target);
-
- maybe_create_hover_effect (target);
- return;
- }
-
- public void remove_hover_effect () {
- hover_layer.add_drawable (null);
- hover_layer.set_visible (false);
- current_hovered_id = -1;
- }
-
- public void maybe_create_hover_effect_by_id (int id) {
- var node = view_canvas.items_manager.node_from_id (id);
- if (node == null) {
- print ("Failed to create hover effect for %d", id);
- assert (node != null);
- return;
- }
-
- if (view_canvas.selection_manager.item_selected (id)) {
- return;
- }
-
- maybe_create_hover_effect (node);
- }
-
- private void maybe_create_hover_effect (Lib.Items.ModelNode node) {
- if (current_hovered_id == node.id) {
- return;
- }
-
- remove_hover_effect ();
- hover_layer.add_drawable (node.instance.drawable);
- current_hovered_id = node.id;
- hover_changed (node.instance.id);
- }
-}
diff --git a/src/Lib/Managers/ItemsManager.vala b/src/Lib/Managers/ItemsManager.vala
deleted file mode 100644
index a695cf1bb..000000000
--- a/src/Lib/Managers/ItemsManager.vala
+++ /dev/null
@@ -1,713 +0,0 @@
-/**
- * Copyright (c) 2019-2021 Alecaddd (https://alecaddd.com)
- *
- * This file is part of Akira.
- *
- * Akira 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.
-
- * Akira 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 Akira. If not, see .
- *
- * Authored by: Martin "mbfraga" Fraga
- * Authored by: Alessandro "Alecaddd" Castellani
- */
-
-public class Akira.Lib.Managers.ItemsManager : Object, Items.ModelListener {
- private const bool CUSTOM_HITTEST = true;
- public unowned Lib.ViewCanvas view_canvas { get; construct; }
-
- private Lib.Items.Model p_item_model;
-
- public unowned Lib.Items.Model item_model { get { return p_item_model; } }
-
- public ItemsManager (Lib.ViewCanvas canvas) {
- Object (view_canvas: canvas);
- }
-
- construct {
- p_item_model = new Lib.Items.Model.live_model (this, view_canvas);
-
- view_canvas.window.event_bus.selection_align.connect (selection_align);
- }
-
- public void replace_model (Lib.Items.Model replacement) {
- p_item_model = replacement;
- p_item_model.wake (this, true);
- view_canvas.set_model_to_render (p_item_model);
- compile_model ();
- }
-
- public signal void item_added (int id);
- public signal void items_removed (GLib.Array ids);
- public signal void item_transferred (int id);
-
- public void on_item_added (int id) {
- item_added (id);
- }
-
- public void on_item_geometry_changed (int id) {
- view_canvas.selection_manager.on_selection_changed (id);
- }
-
- public void on_items_deleted (GLib.Array ids) {
- items_removed (ids);
- }
-
- public void on_item_transferred (int id) {
- item_transferred (id);
- }
-
- public Lib.Items.ModelInstance? instance_from_id (int id) {
- return item_model.instance_from_id (id);
- }
-
- public Lib.Items.ModelNode? node_from_id (int id) {
- return item_model.node_from_id (id);
- }
-
- public int add_item_to_origin (Lib.Items.ModelInstance instance) {
- return add_item_to_group (Lib.Items.Model.ORIGIN_ID, instance);
- }
-
- public int add_item_to_group (int group_id, Lib.Items.ModelInstance instance, bool pause_compile = false) {
- if (instance == null) {
- return -1;
- }
-
- if (item_model.append_new_item (group_id, instance) <= 0) {
- return -1;
- }
-
- if (!pause_compile) {
- compile_model ();
- }
-
- return instance.id;
- }
-
- public int remove_items (GLib.Array to_remove, bool pause_compile = false) {
- ulong microseconds;
- double seconds;
-
- // create a timer object:
- Timer timer = new Timer ();
-
- var to_delete = new Gee.TreeMap (
- Lib.Items.PositionKey.compare,
- null
- );
-
- var modified_groups = new GLib.Array ();
-
- foreach (var id in to_remove.data) {
- var node = item_model.node_from_id (id);
-
- if (node == null) {
- continue;
- }
-
- var key = new Lib.Items.PositionKey ();
- key.parent_path = node.parent == null ? "" : item_model.path_from_node (node.parent);
- key.pos_in_parent = node.pos_in_parent;
-
- to_delete[key] = node.instance;
-
- if (modified_groups.length == 0) {
- modified_groups.append_val (node.parent.id);
- continue;
- }
-
- foreach (var gid in modified_groups.data) {
- if (gid != node.parent.id) {
- modified_groups.append_val (node.parent.id);
- break;
- }
- }
- }
-
- // Collect the nodes' ids to be removed in order to let the layers UI
- // be aware of what to remove without needing to access selection manager
- // which immediately loses the list of selected nodes.
- var ids_array = new GLib.Array ();
-
- var it = to_delete.bidir_map_iterator ();
- for (var has_next = it.last (); has_next; has_next = it.previous ()) {
- var inst = it.get_value ();
- ids_array.append_val (inst.id);
-
- if (0 != item_model.remove (inst.id, false)) {
- assert (false);
- continue;
- }
- }
-
- foreach (var gid in modified_groups.data) {
- item_model.recalculate_children_stacking (gid);
- }
-
- // TODO: move this to the model, have it collect deleted ids and alert this
- items_removed (ids_array);
-
- if (!pause_compile) {
- compile_model ();
- }
-
- timer.stop ();
- seconds = timer.elapsed (out microseconds);
- print ("Deleted %u items in %s s\n", to_remove.length, seconds.to_string ());
- return 0;
- }
-
- /*
- * Alerts the model to recompile all dirty geometries.
- */
- public void compile_model () {
- item_model.compile_geometries ();
- }
-
- /*
- * Shift items by an amount up or down.
- * If to_end is true, amount is only used for direction (down/up)
- */
- public int shift_items (GLib.Array ids, int amount, bool to_end) {
- if (amount == 0) {
- return 0;
- }
-
- var sorted_tree = new Gee.TreeMap (
- Lib.Items.PositionKey.compare,
- null
- );
-
- var shift_groups = new Gee.ArrayList ();
-
- foreach (var id in ids.data) {
- var node = item_model.node_from_id (id);
- if (node == null) {
- continue;
- }
-
- var key = new Lib.Items.PositionKey ();
- key.parent_path = node.parent == null ? "" : item_model.path_from_node (node.parent);
- key.pos_in_parent = node.pos_in_parent;
-
- sorted_tree[key] = node;
- }
-
- Lib.Items.ChildrenSet current_set = null;
- int last_group_id = -1;
- int last_pos = -1;
- foreach (var mapit in sorted_tree) {
- var snode = mapit.value;
- bool is_next = last_group_id == snode.parent.id && snode.pos_in_parent == last_pos + 1;
-
- if (!is_next) {
- last_group_id = snode.parent.id;
- last_pos = snode.pos_in_parent;
-
- current_set = new Lib.Items.ChildrenSet ();
- current_set.parent_node = snode.parent;
- current_set.first_child = last_pos;
- current_set.children_in_set = new GLib.Array ();
- current_set.children_in_set.append_val (snode);
- current_set.length = 1;
-
- shift_groups.add (current_set);
- continue;
- }
-
- last_pos = snode.pos_in_parent;
- current_set.children_in_set.append_val (snode);
- current_set.length++;
- }
-
- bool no_operation_yet = true;
- Utils.TrivialDelegate prep = () => {
- view_canvas.window.event_bus.create_model_snapshot ("shift items' z-order");
- // run only once
- no_operation_yet = false;
- };
-
- view_canvas.pause_redraw = true;
- foreach (var cs in shift_groups) {
- var pos = cs.first_child;
-
- var newpos = pos + amount;
-
- if (to_end) {
- newpos = (amount > 0) ? (int)(cs.parent_node.children.length - cs.length) : 0;
- }
-
- if (newpos < 0) {
- newpos = 0;
- }
-
- if (newpos + cs.length > cs.parent_node.children.length) {
- newpos = (int)(cs.parent_node.children.length - cs.length);
- }
-
- if (newpos < 0 || newpos + cs.length > cs.parent_node.children.length) {
- cs = null;
- // at edges, nothing to do
- continue;
- }
-
- if (0 >= item_model.move_items (cs.parent_node.id, pos, newpos, cs.length, true, prep)) {
- // no items were shifted
- cs = null;
- continue;
- }
- }
-
- view_canvas.pause_redraw = false;
- compile_model ();
- view_canvas.request_redraw (view_canvas.get_bounds ());
-
- return 0;
- }
-
- public void flip_items (GLib.Array