Compare commits
13 Commits
Author | SHA1 | Date |
---|---|---|
william | bc4e44d9c8 | |
william | 9bc67682ad | |
FyloZ | 8e0bf14cc8 | |
FyloZ | 2ef3557932 | |
FyloZ | efa5858859 | |
FyloZ | 24cfc7122f | |
FyloZ | d44616bd72 | |
william | 93d460ae5d | |
FyloZ | 7cc7d3bb76 | |
william | d793297ad5 | |
FyloZ | c124d6ccdb | |
william | 71210dfdac | |
william | f8d1608036 |
|
@ -0,0 +1,11 @@
|
|||
{
|
||||
"configurations": [
|
||||
{
|
||||
"type": "cargo",
|
||||
"cargoArgs": [
|
||||
"run"
|
||||
],
|
||||
"name": "Cargo configuration"
|
||||
}
|
||||
]
|
||||
}
|
|
@ -2,6 +2,907 @@
|
|||
# It is not intended for manual editing.
|
||||
version = 3
|
||||
|
||||
[[package]]
|
||||
name = "anyhow"
|
||||
version = "1.0.75"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a4668cab20f66d8d020e1fbc0ebe47217433c1b6c8f2040faf858554e394ace6"
|
||||
|
||||
[[package]]
|
||||
name = "autocfg"
|
||||
version = "1.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa"
|
||||
|
||||
[[package]]
|
||||
name = "bitflags"
|
||||
version = "2.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b4682ae6287fcf752ecaabbfcc7b6f9b72aa33933dc23a554d853aea8eea8635"
|
||||
|
||||
[[package]]
|
||||
name = "cairo-rs"
|
||||
version = "0.18.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d859b656775a6b1dd078d3e5924884e6ea88aa649a7fdde03d5b2ec56ffcc10b"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"cairo-sys-rs",
|
||||
"glib",
|
||||
"libc",
|
||||
"once_cell",
|
||||
"thiserror",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cairo-sys-rs"
|
||||
version = "0.18.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bd4d115132e01c0165e3bf5f56aedee8980b0b96ede4eb000b693c05a8adb8ff"
|
||||
dependencies = [
|
||||
"glib-sys",
|
||||
"libc",
|
||||
"system-deps",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cfg-expr"
|
||||
version = "0.15.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "03915af431787e6ffdcc74c645077518c6b6e01f80b761e0fbbfa288536311b3"
|
||||
dependencies = [
|
||||
"smallvec",
|
||||
"target-lexicon",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cfg-if"
|
||||
version = "1.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
|
||||
|
||||
[[package]]
|
||||
name = "config-manager-client"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"f-uuid",
|
||||
"gio",
|
||||
"glib-build-tools",
|
||||
"gtk4",
|
||||
"libadwaita",
|
||||
"log",
|
||||
"simplelog",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "deranged"
|
||||
version = "0.3.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f2696e8a945f658fd14dc3b87242e6b80cd0f36ff04ea560fa39082368847946"
|
||||
|
||||
[[package]]
|
||||
name = "equivalent"
|
||||
version = "1.0.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5"
|
||||
|
||||
[[package]]
|
||||
name = "f-uuid"
|
||||
version = "1.0.0"
|
||||
source = "registry+https://gitea.fyloz.dev/william/_cargo-index.git"
|
||||
checksum = "ba73c5b8fcda058d64a8ce4d89a37b1457cedf0a50759b601f55581c958533ec"
|
||||
dependencies = [
|
||||
"getrandom",
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[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.28"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "955518d47e09b25bbebc7a18df10b81f0c766eaf4c4f1cccef2fca5f2a4fb5f2"
|
||||
dependencies = [
|
||||
"futures-core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "futures-core"
|
||||
version = "0.3.28"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4bca583b7e26f571124fe5b7561d49cb2868d79116cfa0eefce955557c6fee8c"
|
||||
|
||||
[[package]]
|
||||
name = "futures-executor"
|
||||
version = "0.3.28"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ccecee823288125bd88b4d7f565c9e58e41858e47ab72e8ea2d64e93624386e0"
|
||||
dependencies = [
|
||||
"futures-core",
|
||||
"futures-task",
|
||||
"futures-util",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "futures-io"
|
||||
version = "0.3.28"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4fff74096e71ed47f8e023204cfd0aa1289cd54ae5430a9523be060cdb849964"
|
||||
|
||||
[[package]]
|
||||
name = "futures-macro"
|
||||
version = "0.3.28"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "89ca545a94061b6365f2c7355b4b32bd20df3ff95f02da9329b34ccc3bd6ee72"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.31",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "futures-task"
|
||||
version = "0.3.28"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "76d3d132be6c0e6aa1534069c705a74a5997a356c0dc2f86a47765e5617c5b65"
|
||||
|
||||
[[package]]
|
||||
name = "futures-util"
|
||||
version = "0.3.28"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "26b01e40b772d54cf6c6d721c1d1abd0647a0106a12ecaa1c186273392a69533"
|
||||
dependencies = [
|
||||
"futures-core",
|
||||
"futures-macro",
|
||||
"futures-task",
|
||||
"pin-project-lite",
|
||||
"pin-utils",
|
||||
"slab",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "gdk-pixbuf"
|
||||
version = "0.18.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bbc9c2ed73a81d556b65d08879ba4ee58808a6b1927ce915262185d6d547c6f3"
|
||||
dependencies = [
|
||||
"gdk-pixbuf-sys",
|
||||
"gio",
|
||||
"glib",
|
||||
"libc",
|
||||
"once_cell",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "gdk-pixbuf-sys"
|
||||
version = "0.18.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3f9839ea644ed9c97a34d129ad56d38a25e6756f99f3a88e15cd39c20629caf7"
|
||||
dependencies = [
|
||||
"gio-sys",
|
||||
"glib-sys",
|
||||
"gobject-sys",
|
||||
"libc",
|
||||
"system-deps",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "gdk4"
|
||||
version = "0.7.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6982d9815ed6ac95b0467b189e81f29dea26d08a732926ec113e65744ed3f96c"
|
||||
dependencies = [
|
||||
"cairo-rs",
|
||||
"gdk-pixbuf",
|
||||
"gdk4-sys",
|
||||
"gio",
|
||||
"glib",
|
||||
"libc",
|
||||
"pango",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "gdk4-sys"
|
||||
version = "0.7.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dbab43f332a3cf1df9974da690b5bb0e26720ed09a228178ce52175372dcfef0"
|
||||
dependencies = [
|
||||
"cairo-sys-rs",
|
||||
"gdk-pixbuf-sys",
|
||||
"gio-sys",
|
||||
"glib-sys",
|
||||
"gobject-sys",
|
||||
"libc",
|
||||
"pango-sys",
|
||||
"pkg-config",
|
||||
"system-deps",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "getrandom"
|
||||
version = "0.2.10"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "be4136b2a15dd319360be1c07d9933517ccf0be8f16bf62a3bee4f0d618df427"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"libc",
|
||||
"wasi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "gio"
|
||||
version = "0.18.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "57052f84e8e5999b258e8adf8f5f2af0ac69033864936b8b6838321db2f759b1"
|
||||
dependencies = [
|
||||
"futures-channel",
|
||||
"futures-core",
|
||||
"futures-io",
|
||||
"futures-util",
|
||||
"gio-sys",
|
||||
"glib",
|
||||
"libc",
|
||||
"once_cell",
|
||||
"pin-project-lite",
|
||||
"smallvec",
|
||||
"thiserror",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "gio-sys"
|
||||
version = "0.18.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "37566df850baf5e4cb0dfb78af2e4b9898d817ed9263d1090a2df958c64737d2"
|
||||
dependencies = [
|
||||
"glib-sys",
|
||||
"gobject-sys",
|
||||
"libc",
|
||||
"system-deps",
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "glib"
|
||||
version = "0.18.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "331156127e8166dd815cf8d2db3a5beb492610c716c03ee6db4f2d07092af0a7"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"futures-channel",
|
||||
"futures-core",
|
||||
"futures-executor",
|
||||
"futures-task",
|
||||
"futures-util",
|
||||
"gio-sys",
|
||||
"glib-macros",
|
||||
"glib-sys",
|
||||
"gobject-sys",
|
||||
"libc",
|
||||
"memchr",
|
||||
"once_cell",
|
||||
"smallvec",
|
||||
"thiserror",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "glib-build-tools"
|
||||
version = "0.18.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3431c56f463443cba9bc3600248bc6d680cb614c2ee1cdd39dab5415bd12ac5c"
|
||||
|
||||
[[package]]
|
||||
name = "glib-macros"
|
||||
version = "0.18.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "179643c50bf28d20d2f6eacd2531a88f2f5d9747dd0b86b8af1e8bb5dd0de3c0"
|
||||
dependencies = [
|
||||
"heck",
|
||||
"proc-macro-crate",
|
||||
"proc-macro-error",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.31",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "glib-sys"
|
||||
version = "0.18.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "063ce2eb6a8d0ea93d2bf8ba1957e78dbab6be1c2220dd3daca57d5a9d869898"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"system-deps",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "gobject-sys"
|
||||
version = "0.18.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0850127b514d1c4a4654ead6dedadb18198999985908e6ffe4436f53c785ce44"
|
||||
dependencies = [
|
||||
"glib-sys",
|
||||
"libc",
|
||||
"system-deps",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "graphene-rs"
|
||||
version = "0.18.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3b2228cda1505613a7a956cca69076892cfbda84fc2b7a62b94a41a272c0c401"
|
||||
dependencies = [
|
||||
"glib",
|
||||
"graphene-sys",
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "graphene-sys"
|
||||
version = "0.18.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cc4144cee8fc8788f2a9b73dc5f1d4e1189d1f95305c4cb7bd9c1af1cfa31f59"
|
||||
dependencies = [
|
||||
"glib-sys",
|
||||
"libc",
|
||||
"pkg-config",
|
||||
"system-deps",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "gsk4"
|
||||
version = "0.7.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cc25855255120f294d874acd6eaf4fbed7ce1cdc550e2d8415ea57fafbe816d5"
|
||||
dependencies = [
|
||||
"cairo-rs",
|
||||
"gdk4",
|
||||
"glib",
|
||||
"graphene-rs",
|
||||
"gsk4-sys",
|
||||
"libc",
|
||||
"pango",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "gsk4-sys"
|
||||
version = "0.7.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e1ecf3a63bf1223d68f80f72cc896c4d8c80482fbce1c9a12c66d3de7290ee46"
|
||||
dependencies = [
|
||||
"cairo-sys-rs",
|
||||
"gdk4-sys",
|
||||
"glib-sys",
|
||||
"gobject-sys",
|
||||
"graphene-sys",
|
||||
"libc",
|
||||
"pango-sys",
|
||||
"system-deps",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "gtk4"
|
||||
version = "0.7.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a3b095b26f2a2df70be1805d3590eeb9d7a05ecb5be9649b82defc72dc56228c"
|
||||
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.7.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d57ec49cf9b657f69a05bca8027cff0a8dfd0c49e812be026fc7311f2163832f"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"proc-macro-crate",
|
||||
"proc-macro-error",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 1.0.109",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "gtk4-sys"
|
||||
version = "0.7.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7b0bdde87c50317b4f355bcbb4a9c2c414ece1b7c824fb4ad4ba8f3bdb2c6603"
|
||||
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.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2c6201b9ff9fd90a5a3bac2e56a830d0caa509576f0e503818ee82c181b3437a"
|
||||
|
||||
[[package]]
|
||||
name = "heck"
|
||||
version = "0.4.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8"
|
||||
|
||||
[[package]]
|
||||
name = "indexmap"
|
||||
version = "2.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d5477fe2230a79769d8dc68e0eabf5437907c0457a5614a9e8dddb67f65eb65d"
|
||||
dependencies = [
|
||||
"equivalent",
|
||||
"hashbrown",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "itoa"
|
||||
version = "1.0.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "af150ab688ff2122fcef229be89cb50dd66af9e01a4ff320cc137eecc9bacc38"
|
||||
|
||||
[[package]]
|
||||
name = "libadwaita"
|
||||
version = "0.5.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "06444f4ca05a60693da6e9e2b591bd40a298e65a118a8d5e830771718b3e0253"
|
||||
dependencies = [
|
||||
"gdk-pixbuf",
|
||||
"gdk4",
|
||||
"gio",
|
||||
"glib",
|
||||
"gtk4",
|
||||
"libadwaita-sys",
|
||||
"libc",
|
||||
"pango",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "libadwaita-sys"
|
||||
version = "0.5.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "021cfe3d1fcfa82411765a791f7e9b32f35dd98ce88d2e3fa10e7320f5cc8ce7"
|
||||
dependencies = [
|
||||
"gdk4-sys",
|
||||
"gio-sys",
|
||||
"glib-sys",
|
||||
"gobject-sys",
|
||||
"gtk4-sys",
|
||||
"libc",
|
||||
"pango-sys",
|
||||
"system-deps",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "libc"
|
||||
version = "0.2.147"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b4668fb0ea861c1df094127ac5f1da3409a82116a4ba74fca2e58ef927159bb3"
|
||||
|
||||
[[package]]
|
||||
name = "log"
|
||||
version = "0.4.20"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f"
|
||||
|
||||
[[package]]
|
||||
name = "memchr"
|
||||
version = "2.6.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8f232d6ef707e1956a43342693d2a31e72989554d58299d7a88738cc95b0d35c"
|
||||
|
||||
[[package]]
|
||||
name = "memoffset"
|
||||
version = "0.9.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5a634b1c61a95585bd15607c6ab0c4e5b226e695ff2800ba0cdccddf208c406c"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num_threads"
|
||||
version = "0.1.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2819ce041d2ee131036f4fc9d6ae7ae125a3a40e97ba64d04fe799ad9dabbb44"
|
||||
dependencies = [
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "once_cell"
|
||||
version = "1.18.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d"
|
||||
|
||||
[[package]]
|
||||
name = "pango"
|
||||
version = "0.18.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "06a9e54b831d033206160096b825f2070cf5fda7e35167b1c01e9e774f9202d1"
|
||||
dependencies = [
|
||||
"gio",
|
||||
"glib",
|
||||
"libc",
|
||||
"once_cell",
|
||||
"pango-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pango-sys"
|
||||
version = "0.18.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "436737e391a843e5933d6d9aa102cb126d501e815b83601365a948a518555dc5"
|
||||
dependencies = [
|
||||
"glib-sys",
|
||||
"gobject-sys",
|
||||
"libc",
|
||||
"system-deps",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pin-project-lite"
|
||||
version = "0.2.13"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8afb450f006bf6385ca15ef45d71d2288452bc3683ce2e2cacc0d18e4be60b58"
|
||||
|
||||
[[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.27"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "26072860ba924cbfa98ea39c8c19b4dd6a4a25423dbdf219c1eca91aa0cf6964"
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro-crate"
|
||||
version = "1.3.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7f4c021e1093a56626774e81216a4ce732a735e5bad4868a03f3ed65ca0c3919"
|
||||
dependencies = [
|
||||
"once_cell",
|
||||
"toml_edit",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro-error"
|
||||
version = "1.0.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c"
|
||||
dependencies = [
|
||||
"proc-macro-error-attr",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 1.0.109",
|
||||
"version_check",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro-error-attr"
|
||||
version = "1.0.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"version_check",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro2"
|
||||
version = "1.0.66"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "18fb31db3f9bddb2ea821cde30a9f70117e3f119938b5ee630b7403aa6e2ead9"
|
||||
dependencies = [
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "quote"
|
||||
version = "1.0.33"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rustc_version"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366"
|
||||
dependencies = [
|
||||
"semver",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "semver"
|
||||
version = "1.0.18"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b0293b4b29daaf487284529cc2f5675b8e57c61f70167ba415a463651fd6a918"
|
||||
|
||||
[[package]]
|
||||
name = "serde"
|
||||
version = "1.0.188"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cf9e0fcba69a370eed61bcf2b728575f726b50b55cba78064753d708ddc7549e"
|
||||
dependencies = [
|
||||
"serde_derive",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_derive"
|
||||
version = "1.0.188"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4eca7ac642d82aa35b60049a6eccb4be6be75e599bd2e9adb5f875a737654af2"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.31",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_spanned"
|
||||
version = "0.6.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "96426c9936fd7a0124915f9185ea1d20aa9445cc9821142f0a73bc9207a2e186"
|
||||
dependencies = [
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "simplelog"
|
||||
version = "0.12.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "acee08041c5de3d5048c8b3f6f13fafb3026b24ba43c6a695a0c76179b844369"
|
||||
dependencies = [
|
||||
"log",
|
||||
"termcolor",
|
||||
"time",
|
||||
]
|
||||
|
||||
[[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.11.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "62bb4feee49fdd9f707ef802e22365a35de4b7b299de4763d44bfea899442ff9"
|
||||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "1.0.109"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "2.0.31"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "718fa2415bcb8d8bd775917a1bf12a7931b6dfa890753378538118181e0cb398"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "system-deps"
|
||||
version = "6.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "30c2de8a4d8f4b823d634affc9cd2a74ec98c53a756f317e529a48046cbf71f3"
|
||||
dependencies = [
|
||||
"cfg-expr",
|
||||
"heck",
|
||||
"pkg-config",
|
||||
"toml",
|
||||
"version-compare",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "target-lexicon"
|
||||
version = "0.12.11"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9d0e916b1148c8e263850e1ebcbd046f333e0683c724876bb0da63ea4373dc8a"
|
||||
|
||||
[[package]]
|
||||
name = "termcolor"
|
||||
version = "1.1.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bab24d30b911b2376f3a13cc2cd443142f0c81dda04c118693e35b3835757755"
|
||||
dependencies = [
|
||||
"winapi-util",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "thiserror"
|
||||
version = "1.0.48"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9d6d7a740b8a666a7e828dd00da9c0dc290dff53154ea77ac109281de90589b7"
|
||||
dependencies = [
|
||||
"thiserror-impl",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "thiserror-impl"
|
||||
version = "1.0.48"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "49922ecae66cc8a249b77e68d1d0623c1b2c514f0060c27cdc68bd62a1219d35"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.31",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "time"
|
||||
version = "0.3.28"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "17f6bb557fd245c28e6411aa56b6403c689ad95061f50e4be16c274e70a17e48"
|
||||
dependencies = [
|
||||
"deranged",
|
||||
"itoa",
|
||||
"libc",
|
||||
"num_threads",
|
||||
"serde",
|
||||
"time-core",
|
||||
"time-macros",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "time-core"
|
||||
version = "0.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7300fbefb4dadc1af235a9cef3737cea692a9d97e1b9cbcd4ebdae6f8868e6fb"
|
||||
|
||||
[[package]]
|
||||
name = "time-macros"
|
||||
version = "0.2.14"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1a942f44339478ef67935ab2bbaec2fb0322496cf3cbe84b261e06ac3814c572"
|
||||
dependencies = [
|
||||
"time-core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "toml"
|
||||
version = "0.7.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dd79e69d3b627db300ff956027cc6c3798cef26d22526befdfcd12feeb6d2257"
|
||||
dependencies = [
|
||||
"serde",
|
||||
"serde_spanned",
|
||||
"toml_datetime",
|
||||
"toml_edit",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "toml_datetime"
|
||||
version = "0.6.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7cda73e2f1397b1262d6dfdcef8aafae14d1de7748d66822d3bfeeb6d03e5e4b"
|
||||
dependencies = [
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "toml_edit"
|
||||
version = "0.19.15"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1b5bb770da30e5cbfde35a2d7b9b8a2c4b8ef89548a7a6aeab5c9a576e3e7421"
|
||||
dependencies = [
|
||||
"indexmap",
|
||||
"serde",
|
||||
"serde_spanned",
|
||||
"toml_datetime",
|
||||
"winnow",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "unicode-ident"
|
||||
version = "1.0.11"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "301abaae475aa91687eb82514b328ab47a211a533026cb25fc3e519b86adfc3c"
|
||||
|
||||
[[package]]
|
||||
name = "version-compare"
|
||||
version = "0.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "579a42fc0b8e0c63b76519a339be31bed574929511fa53c1a3acae26eb258f29"
|
||||
|
||||
[[package]]
|
||||
name = "version_check"
|
||||
version = "0.9.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f"
|
||||
|
||||
[[package]]
|
||||
name = "wasi"
|
||||
version = "0.11.0+wasi-snapshot-preview1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
|
||||
|
||||
[[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-util"
|
||||
version = "0.1.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178"
|
||||
dependencies = [
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[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 = "winnow"
|
||||
version = "0.5.15"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7c2e3184b9c4e92ad5167ca73039d0c42476302ab603e2fec4487511f38ccefc"
|
||||
dependencies = [
|
||||
"memchr",
|
||||
]
|
||||
|
|
|
@ -6,3 +6,12 @@ edition = "2021"
|
|||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies]
|
||||
adw = { version = "0.5.2", package = "libadwaita", features = ["v1_3"] }
|
||||
f-uuid = { version = "1.0.0", registry = "gitea" }
|
||||
gio = { version = "0.18.2", features = ["v2_74"] }
|
||||
gtk = { version = "0.7.1", package = "gtk4", features = ["v4_10"] }
|
||||
log = { version = "0.4", features = ["max_level_debug", "release_max_level_info"] }
|
||||
simplelog = "^0.12.0"
|
||||
|
||||
[build-dependencies]
|
||||
glib-build-tools = "0.18.0"
|
||||
|
|
|
@ -0,0 +1,7 @@
|
|||
fn main() {
|
||||
glib_build_tools::compile_resources(
|
||||
&["resources"],
|
||||
"resources/resources.gresource.xml",
|
||||
"resources.gresource"
|
||||
)
|
||||
}
|
|
@ -0,0 +1,21 @@
|
|||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<interface>
|
||||
<template class="CmAppView" parent="GtkBox">
|
||||
<property name="orientation">vertical</property>
|
||||
<property name="hexpand">True</property>
|
||||
<child>
|
||||
<object class="GtkButton" id="button">
|
||||
<property name="halign">center</property>
|
||||
<property name="child">
|
||||
<object class="AdwButtonContent">
|
||||
<property name="icon-name">user-trash-symbolic</property>
|
||||
<property name="label" translatable="yes">Remove</property>
|
||||
</object>
|
||||
</property>
|
||||
<style>
|
||||
<class name="destructive-action" />
|
||||
</style>
|
||||
</object>
|
||||
</child>
|
||||
</template>
|
||||
</interface>
|
|
@ -0,0 +1,7 @@
|
|||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<gresources>
|
||||
<gresource prefix="/dev/fyloz/example/">
|
||||
<file compressed="true" preprocess="xml-stripblanks">window.ui</file>
|
||||
<file compressed="true" preprocess="xml-stripblanks">app_view.ui</file>
|
||||
</gresource>
|
||||
</gresources>
|
|
@ -0,0 +1,143 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<interface>
|
||||
<menu id="main-menu">
|
||||
<!-- Menu -->
|
||||
</menu>
|
||||
<template class="ConfigManagerWindow" parent="AdwApplicationWindow">
|
||||
<property name="default-height">720</property>
|
||||
<property name="default-width">1280</property>
|
||||
<property name="title">Config Manager</property>
|
||||
<property name="content">
|
||||
<object class="GtkStack" id="stack">
|
||||
<property name="transition-type">crossfade</property>
|
||||
<child>
|
||||
<object class="GtkStackPage">
|
||||
<property name="name">empty</property>
|
||||
<property name="child">
|
||||
<object class="GtkBox">
|
||||
<!-- Placeholder -->
|
||||
<property name="orientation">vertical</property>
|
||||
<child>
|
||||
<object class="GtkHeaderBar">
|
||||
<style>
|
||||
<class name="flat" />
|
||||
</style>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkWindowHandle">
|
||||
<property name="vexpand">True</property>
|
||||
<property name="child">
|
||||
<object class="AdwStatusPage">
|
||||
<property name="icon-name">checkbox-checked-symbolic</property>
|
||||
<property name="title" translatable="yes">No Applications</property>
|
||||
<property name="description" translatable="yes">Add an application to start using this app.</property>
|
||||
<property name="child">
|
||||
<object class="GtkButton">
|
||||
<property name="label" translatable="yes">_New Application</property>
|
||||
<property name="use-underline">True</property>
|
||||
<property name="halign">center</property>
|
||||
<property name="action-name">win.new-application</property>
|
||||
<style>
|
||||
<class name="pill" />
|
||||
<class name="suggested-action" />
|
||||
</style>
|
||||
</object>
|
||||
</property>
|
||||
</object>
|
||||
</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkStackPage">
|
||||
<property name="name">main</property>
|
||||
<property name="child">
|
||||
<object class="AdwLeaflet" id="leaflet">
|
||||
<property name="can-navigate-back">True</property>
|
||||
<child>
|
||||
<object class="GtkBox">
|
||||
<property name="orientation">vertical</property>
|
||||
<property name="width-request">199</property>
|
||||
<child>
|
||||
<object class="AdwHeaderBar">
|
||||
<binding name="show-end-title-buttons">
|
||||
<lookup name="folded">leaflet</lookup>
|
||||
</binding>
|
||||
<child type="start">
|
||||
<object class="GtkToggleButton">
|
||||
<property name="icon-name">list-add-symbolic</property>
|
||||
<property name="tooltip-text" translatable="yes">New Application</property>
|
||||
<property name="action-name">win.new-application</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<!-- Sidebar -->
|
||||
<child>
|
||||
<object class="GtkScrolledWindow">
|
||||
<property name="vexpand">True</property>
|
||||
<property name="child">
|
||||
<object class="GtkListBox" id="apps_list">
|
||||
<style>
|
||||
<class name="navigation-sidebar" />
|
||||
</style>
|
||||
</object>
|
||||
</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="AdwLeafletPage">
|
||||
<property name="navigatable">False</property>
|
||||
<property name="child">
|
||||
<object class="GtkSeparator" />
|
||||
</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkBox">
|
||||
<property name="orientation">vertical</property>
|
||||
<property name="hexpand">True</property>
|
||||
<property name="width-request">249</property>
|
||||
<child>
|
||||
<object class="AdwHeaderBar">
|
||||
<property name="title-widget">
|
||||
<object class="AdwWindowTitle" />
|
||||
</property>
|
||||
<child>
|
||||
<object class="GtkButton">
|
||||
<binding name="visible">
|
||||
<lookup name="folded">leaflet</lookup>
|
||||
</binding>
|
||||
<property name="icon-name">go-previous-symbolic</property>
|
||||
<property name="tooltip-text" translatable="yes">Back</property>
|
||||
</object>
|
||||
</child>
|
||||
<child type="end">
|
||||
<object class="GtkMenuButton">
|
||||
<property name="icon-name">open-menu-symbolic</property>
|
||||
<property name="menu-model">main-menu</property>
|
||||
<property name="tooltip-text" translatable="yes">Main Menu</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<!-- Content -->
|
||||
<child>
|
||||
<object class="CmAppView" id="app_view" />
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</property>
|
||||
</template>
|
||||
</interface>
|
|
@ -0,0 +1,327 @@
|
|||
// Based on https://github.com/mathertel/Diff
|
||||
// "An O(ND) Difference Algorithm and its Variations" by Eugene Myers Algorithmica Vol. 1 No. 2, 1986, p 251.
|
||||
use std::collections::HashMap;
|
||||
use std::io::{BufRead};
|
||||
use crate::diff::IndexDirection::{None, LeftDown, RightUp};
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct DiffItem {
|
||||
start_a: usize,
|
||||
start_b: usize,
|
||||
deleted_a: usize,
|
||||
inserted_b: usize,
|
||||
}
|
||||
|
||||
struct DiffData {
|
||||
length: usize,
|
||||
codes: Vec<usize>,
|
||||
modified: Vec<bool>,
|
||||
}
|
||||
|
||||
struct SmsData {
|
||||
x: usize,
|
||||
y: usize,
|
||||
}
|
||||
|
||||
struct SmsBounds {
|
||||
lower_a: usize,
|
||||
lower_b: usize,
|
||||
upper_a: usize,
|
||||
upper_b: usize,
|
||||
max_d: usize,
|
||||
down_k: i32,
|
||||
up_k: i32,
|
||||
down_offset: usize,
|
||||
up_offset: usize,
|
||||
is_delta_odd: bool,
|
||||
}
|
||||
|
||||
impl SmsBounds {
|
||||
fn from(lower_a: usize, lower_b: usize, upper_a: usize, upper_b: usize) -> Self {
|
||||
let max = upper_a + upper_b + 1;
|
||||
let max_d = (upper_a - lower_a + upper_b - lower_b) / 2 + 1;
|
||||
|
||||
let down_k = lower_a as i32 - lower_b as i32;
|
||||
let up_k = upper_a as i32 - upper_b as i32;
|
||||
|
||||
let down_offset = (max as i32 - down_k) as usize;
|
||||
let up_offset = (max as i32 - up_k) as usize;
|
||||
|
||||
let is_delta_odd = ((upper_a + lower_a + upper_b + lower_b) & 1) != 0;
|
||||
|
||||
SmsBounds {
|
||||
lower_a,
|
||||
lower_b,
|
||||
upper_a,
|
||||
upper_b,
|
||||
max_d,
|
||||
down_k,
|
||||
up_k,
|
||||
down_offset,
|
||||
up_offset,
|
||||
is_delta_odd,
|
||||
}
|
||||
}
|
||||
|
||||
fn get_down_index(&self, k: i32, dir: IndexDirection) -> usize {
|
||||
self.get_index(self.down_offset, k, dir)
|
||||
}
|
||||
|
||||
fn get_up_index(&self, k: i32, dir: IndexDirection) -> usize {
|
||||
self.get_index(self.up_offset, k, dir)
|
||||
}
|
||||
|
||||
fn get_index(&self, offset: usize, k: i32, dir: IndexDirection) -> usize {
|
||||
(offset as i32 + k + dir as i32) as usize
|
||||
}
|
||||
}
|
||||
|
||||
#[repr(i32)]
|
||||
enum IndexDirection {
|
||||
None = 0,
|
||||
LeftDown = 1, // Down: Down, Up: Left
|
||||
RightUp = -1, // Down: Up, Up: Right
|
||||
}
|
||||
|
||||
// https://stackoverflow.com/questions/54035728/how-to-add-a-negative-i32-number-to-an-usize-variable
|
||||
fn add_i32(index: usize, offset: i32) -> usize {
|
||||
if offset.is_negative() {
|
||||
index - offset.wrapping_abs() as u32 as usize
|
||||
} else {
|
||||
index + offset as usize
|
||||
}
|
||||
}
|
||||
|
||||
pub fn diff<T>(a: &mut T, b: &mut T) -> Vec<DiffItem>
|
||||
where T: BufRead {
|
||||
let mut existing_hashes: HashMap<String, usize> = HashMap::new();
|
||||
let mut data_a = diff_data(a, &mut existing_hashes);
|
||||
let mut data_b = diff_data(b, &mut existing_hashes);
|
||||
|
||||
let max = data_a.length + data_b.length;
|
||||
let mut down_vector = vec![0usize; 2 * max + 2];
|
||||
let mut up_vector = vec![0usize; 2 * max + 2];
|
||||
|
||||
let upper_a = data_a.length;
|
||||
let upper_b = data_b.length;
|
||||
|
||||
lcs(&mut data_a, 0, upper_a, &mut data_b, 0, upper_b, &mut down_vector, &mut up_vector);
|
||||
|
||||
optimize(&mut data_a);
|
||||
optimize(&mut data_b);
|
||||
|
||||
create_diffs(&data_a, &data_b)
|
||||
}
|
||||
|
||||
fn diff_data<T>(reader: &mut T, existing_hashes: &mut HashMap<String, usize>) -> DiffData
|
||||
where T: BufRead {
|
||||
let codes = diff_codes(reader, existing_hashes);
|
||||
let length = codes.len();
|
||||
|
||||
DiffData {
|
||||
length,
|
||||
codes,
|
||||
modified: vec![false; length + 2],
|
||||
}
|
||||
}
|
||||
|
||||
fn diff_codes<T>(reader: &mut T, existing_hashes: &mut HashMap<String, usize>) -> Vec<usize>
|
||||
where T: BufRead {
|
||||
let mut codes = Vec::new();
|
||||
let mut next_code = existing_hashes.len() + 1;
|
||||
|
||||
loop {
|
||||
let mut line = String::new();
|
||||
let read_res = reader.read_line(&mut line).expect("Failed to read BufRead");
|
||||
if read_res == 0 {
|
||||
break;
|
||||
}
|
||||
|
||||
if !existing_hashes.contains_key(&line) {
|
||||
existing_hashes.insert(line, next_code);
|
||||
codes.push(next_code);
|
||||
next_code += 1;
|
||||
} else {
|
||||
codes.push(existing_hashes[&line]);
|
||||
}
|
||||
}
|
||||
|
||||
return codes;
|
||||
}
|
||||
|
||||
// Longest Common-Subsequence
|
||||
fn lcs(data_a: &mut DiffData, mut lower_a: usize, mut upper_a: usize, data_b: &mut DiffData, mut lower_b: usize, mut upper_b: usize, down_vector: &mut Vec<usize>, up_vector: &mut Vec<usize>) {
|
||||
while lower_a < upper_a && lower_b < upper_b && data_a.codes[lower_a] == data_b.codes[lower_b] {
|
||||
lower_a += 1;
|
||||
lower_b += 1;
|
||||
}
|
||||
|
||||
while lower_a < upper_a && lower_b < upper_b && data_a.codes[upper_a - 1] == data_b.codes[upper_b - 1] {
|
||||
upper_a -= 1;
|
||||
upper_b -= 1;
|
||||
}
|
||||
|
||||
if lower_a == upper_a {
|
||||
// Inserted lines
|
||||
while lower_b < upper_b {
|
||||
data_b.modified[lower_b] = true;
|
||||
lower_b += 1;
|
||||
}
|
||||
} else if lower_b == upper_b {
|
||||
// Deleted lines
|
||||
while lower_a < upper_a {
|
||||
data_a.modified[lower_a] = true;
|
||||
lower_a += 1;
|
||||
}
|
||||
} else {
|
||||
// Find the middle snake and length of an optimal path for A and B
|
||||
let sms_bounds = SmsBounds::from(lower_a, lower_b, upper_a, upper_b);
|
||||
let sms = sms(&data_a, &data_b, &sms_bounds, down_vector, up_vector);
|
||||
|
||||
// The path is from lower_x to (x, y) and (x, y) to upper_x
|
||||
lcs(data_a, lower_a, sms.x, data_b, lower_b, sms.y, down_vector, up_vector);
|
||||
lcs(data_a, sms.x, upper_a, data_b, sms.y, upper_b, down_vector, up_vector);
|
||||
}
|
||||
}
|
||||
|
||||
// Shortest Middle Snake
|
||||
fn sms(data_a: &DiffData, data_b: &DiffData, bounds: &SmsBounds, down_vector: &mut Vec<usize>, up_vector: &mut Vec<usize>) -> SmsData {
|
||||
down_vector[bounds.get_down_index(bounds.down_k, LeftDown)] = bounds.lower_a;
|
||||
up_vector[bounds.get_up_index(bounds.up_k, RightUp)] = bounds.upper_a;
|
||||
|
||||
for d in 0..=bounds.max_d as i32 {
|
||||
// Extend the forward path
|
||||
for k in ((bounds.down_k - d)..=(bounds.down_k + d)).step_by(2) {
|
||||
let mut x;
|
||||
let mut y;
|
||||
|
||||
if k == bounds.down_k - d {
|
||||
// Down
|
||||
x = down_vector[bounds.get_down_index(k, LeftDown)];
|
||||
} else {
|
||||
// Right
|
||||
x = down_vector[bounds.get_down_index(k, RightUp)] + 1;
|
||||
if k < bounds.down_k + d && down_vector[bounds.get_down_index(k, LeftDown)] >= x {
|
||||
// Down
|
||||
x = down_vector[bounds.get_down_index(k, LeftDown)];
|
||||
}
|
||||
}
|
||||
y = add_i32(x, -k);
|
||||
|
||||
// Find the end of the furthest reaching forward D-path in diagonal k.
|
||||
while x < bounds.upper_a && y < bounds.upper_b && data_a.codes[x] == data_b.codes[y] {
|
||||
x += 1;
|
||||
y += 1;
|
||||
}
|
||||
|
||||
down_vector[bounds.get_down_index(k, None)] = x;
|
||||
|
||||
// Overlap ?
|
||||
if bounds.is_delta_odd && bounds.up_k - d < k && k < bounds.up_k + d &&
|
||||
up_vector[bounds.get_up_index(k, None)] <= down_vector[bounds.get_down_index(k, None)] {
|
||||
let x = down_vector[bounds.get_down_index(k, None)];
|
||||
let y = add_i32(down_vector[bounds.get_down_index(k, None)], -k);
|
||||
return SmsData { x, y };
|
||||
}
|
||||
}
|
||||
|
||||
// Extend the reverse path
|
||||
for k in ((bounds.up_k - d)..=(bounds.up_k + d)).step_by(2) {
|
||||
let mut x;
|
||||
let mut y;
|
||||
|
||||
if k == bounds.up_k + d {
|
||||
// Up
|
||||
x = up_vector[bounds.get_up_index(k, RightUp)];
|
||||
} else {
|
||||
// Left
|
||||
x = up_vector[bounds.get_up_index(k, LeftDown)] - 1;
|
||||
if k > bounds.up_k - d && up_vector[bounds.get_up_index(k, RightUp)] < x {
|
||||
// Up
|
||||
x = up_vector[bounds.get_up_index(k, RightUp)];
|
||||
}
|
||||
}
|
||||
y = add_i32(x, -k);
|
||||
|
||||
while x > bounds.lower_a && y > bounds.lower_b && data_a.codes[x - 1] == data_b.codes[y - 1] {
|
||||
x -= 1;
|
||||
y -= 1;
|
||||
}
|
||||
|
||||
up_vector[bounds.get_up_index(k, None)] = x;
|
||||
|
||||
// Overlap ?
|
||||
if !bounds.is_delta_odd && bounds.down_k - d <= k && k <= bounds.down_k + d &&
|
||||
up_vector[bounds.get_up_index(k, None)] <= down_vector[bounds.get_down_index(k, None)] {
|
||||
let x = down_vector[bounds.get_down_index(k, None)];
|
||||
let y = add_i32(down_vector[bounds.get_down_index(k, None)], -k);
|
||||
return SmsData { x, y };
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
panic!("This should not be possible :(");
|
||||
}
|
||||
|
||||
fn optimize(data: &mut DiffData) {
|
||||
let mut start_pos = 0usize;
|
||||
let mut end_pos;
|
||||
|
||||
while start_pos < data.length {
|
||||
while start_pos < data.length && !data.modified[start_pos] {
|
||||
start_pos += 1;
|
||||
}
|
||||
end_pos = start_pos;
|
||||
while end_pos < data.length && data.modified[end_pos] {
|
||||
end_pos += 1;
|
||||
}
|
||||
|
||||
if end_pos < data.length && data.codes[start_pos] == data.codes[end_pos] {
|
||||
data.modified[start_pos] = false;
|
||||
data.modified[end_pos] = true;
|
||||
} else {
|
||||
start_pos = end_pos;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn create_diffs(data_a: &DiffData, data_b: &DiffData) -> Vec<DiffItem> {
|
||||
let mut result = Vec::new();
|
||||
|
||||
let mut start_a;
|
||||
let mut start_b;
|
||||
let mut line_a = 0usize;
|
||||
let mut line_b = 0usize;
|
||||
|
||||
while line_a < data_a.length || line_b < data_b.length {
|
||||
if line_a < data_a.length && !data_a.modified[line_a] &&
|
||||
line_b < data_b.length && !data_b.modified[line_b] {
|
||||
// Equal line
|
||||
line_a += 1;
|
||||
line_b += 1;
|
||||
} else {
|
||||
start_a = line_a;
|
||||
start_b = line_b;
|
||||
|
||||
while line_a < data_a.length && (line_b >= data_b.length || data_a.modified[line_a]) {
|
||||
line_a += 1;
|
||||
}
|
||||
|
||||
while line_b < data_b.length && (line_a >= data_a.length || data_b.modified[line_b]) {
|
||||
line_b += 1;
|
||||
}
|
||||
|
||||
if start_a < line_a || start_b < line_b {
|
||||
let item = DiffItem {
|
||||
start_a,
|
||||
start_b,
|
||||
deleted_a: line_a - start_a,
|
||||
inserted_b: line_b - start_b,
|
||||
};
|
||||
result.push(item);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
result
|
||||
}
|
26
src/main.rs
26
src/main.rs
|
@ -1,3 +1,25 @@
|
|||
fn main() {
|
||||
println!("Hello, world!");
|
||||
use crate::ui::window::Window;
|
||||
use adw::prelude::*;
|
||||
use gtk::{gio, glib};
|
||||
|
||||
mod diff;
|
||||
mod ui;
|
||||
|
||||
const APP_ID: &str = "dev.fyloz.HelloWorld1";
|
||||
|
||||
fn main() -> glib::ExitCode {
|
||||
gio::resources_register_include!("resources.gresource").expect("Failed to register resources.");
|
||||
|
||||
let app = adw::Application::builder().application_id(APP_ID).build();
|
||||
|
||||
app.connect_activate(build_ui);
|
||||
|
||||
app.run()
|
||||
|
||||
// TermLogger::init(LevelFilter::Debug, Config::default(), TerminalMode::Mixed, ColorChoice::Auto).unwrap();
|
||||
}
|
||||
|
||||
fn build_ui(app: &adw::Application) {
|
||||
let window = Window::new(app);
|
||||
window.present();
|
||||
}
|
||||
|
|
|
@ -0,0 +1,45 @@
|
|||
use std::cell::RefCell;
|
||||
use adw::glib;
|
||||
use glib::subclass::InitializingObject;
|
||||
use gtk::{Button, CompositeTemplate, template_callbacks};
|
||||
use gtk::prelude::*;
|
||||
use gtk::subclass::prelude::*;
|
||||
use crate::ui::objects::app::AppObject;
|
||||
|
||||
#[derive(Default, CompositeTemplate)]
|
||||
#[template(resource = "/dev/fyloz/example/app_view.ui")]
|
||||
pub struct AppView {
|
||||
#[template_child]
|
||||
pub button: TemplateChild<Button>,
|
||||
|
||||
pub application: RefCell<Option<AppObject>>
|
||||
}
|
||||
|
||||
#[template_callbacks]
|
||||
impl AppView {
|
||||
#[template_callback]
|
||||
fn handle_remove_button_clicked(&self, button: &Button) {
|
||||
println!("Clicked!");
|
||||
}
|
||||
}
|
||||
|
||||
#[glib::object_subclass]
|
||||
impl ObjectSubclass for AppView {
|
||||
const NAME: &'static str = "CmAppView";
|
||||
type Type = super::AppView;
|
||||
type ParentType = gtk::Box;
|
||||
|
||||
fn class_init(klass: &mut Self::Class) {
|
||||
klass.bind_template();
|
||||
}
|
||||
|
||||
fn instance_init(obj: &InitializingObject<Self>) {
|
||||
obj.init_template();
|
||||
}
|
||||
}
|
||||
|
||||
impl ObjectImpl for AppView {}
|
||||
|
||||
impl WidgetImpl for AppView {}
|
||||
|
||||
impl BoxImpl for AppView {}
|
|
@ -0,0 +1,18 @@
|
|||
use adw::glib;
|
||||
use adw::subclass::prelude::*;
|
||||
|
||||
use crate::ui::objects::app::AppObject;
|
||||
|
||||
mod imp;
|
||||
|
||||
glib::wrapper! {
|
||||
pub struct AppView(ObjectSubclass<imp::AppView>)
|
||||
@extends gtk::Box, gtk::Widget,
|
||||
@implements gtk::Accessible, gtk::Buildable, gtk::ConstraintTarget, gtk::Orientable;
|
||||
}
|
||||
|
||||
impl AppView {
|
||||
pub fn set_application(&self, app: AppObject) {
|
||||
self.imp().application.replace(Some(app));
|
||||
}
|
||||
}
|
|
@ -0,0 +1,4 @@
|
|||
pub mod objects;
|
||||
pub mod window;
|
||||
|
||||
pub mod appview;
|
|
@ -0,0 +1,26 @@
|
|||
use std::cell::RefCell;
|
||||
|
||||
use adw::prelude::*;
|
||||
use adw::subclass::prelude::*;
|
||||
use glib::Properties;
|
||||
use gtk::glib;
|
||||
|
||||
#[derive(Properties, Default)]
|
||||
#[properties(wrapper_type = super::AppObject)]
|
||||
pub struct AppObject {
|
||||
#[property(get, set)]
|
||||
pub id: RefCell<String>,
|
||||
#[property(get, set)]
|
||||
pub name: RefCell<String>,
|
||||
#[property(get, set)]
|
||||
pub path: RefCell<String>,
|
||||
}
|
||||
|
||||
#[glib::object_subclass]
|
||||
impl ObjectSubclass for AppObject {
|
||||
const NAME: &'static str = "AppObject";
|
||||
type Type = super::AppObject;
|
||||
}
|
||||
|
||||
#[glib::derived_properties]
|
||||
impl ObjectImpl for AppObject {}
|
|
@ -0,0 +1,48 @@
|
|||
mod imp;
|
||||
|
||||
use std::str::FromStr;
|
||||
use adw::subclass::prelude::*;
|
||||
use f_uuid::Uuid;
|
||||
use glib::Object;
|
||||
use gtk::glib;
|
||||
|
||||
glib::wrapper! {
|
||||
pub struct AppObject(ObjectSubclass<imp::AppObject>);
|
||||
}
|
||||
|
||||
impl AppObject {
|
||||
pub fn new(name: &str, path: &str) -> Self {
|
||||
let id = Uuid::new_random();
|
||||
|
||||
AppObject::from_fields(id, name, path)
|
||||
}
|
||||
|
||||
pub fn from_fields(id: Uuid, name: &str, path: &str) -> Self {
|
||||
Object::builder()
|
||||
.property("id", id.to_string())
|
||||
.property("name", name)
|
||||
.property("path", path)
|
||||
.build()
|
||||
}
|
||||
|
||||
pub fn to_app_data(&self) -> AppData {
|
||||
let id_str = &self.imp().id.borrow();
|
||||
let id = Uuid::from_str(id_str).unwrap();
|
||||
|
||||
let name = self.imp().name.borrow().clone();
|
||||
let path = self.imp().path.borrow().clone();
|
||||
|
||||
AppData { id, name, path }
|
||||
}
|
||||
|
||||
pub fn from_app_data(app_data: &AppData) -> Self {
|
||||
Self::from_fields(app_data.id, &app_data.name, &app_data.path)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Default, Clone)]
|
||||
pub struct AppData {
|
||||
pub id: Uuid,
|
||||
pub name: String,
|
||||
pub path: String
|
||||
}
|
|
@ -0,0 +1 @@
|
|||
pub mod app;
|
|
@ -0,0 +1,62 @@
|
|||
use crate::ui::objects::app::AppObject;
|
||||
|
||||
use std::cell::RefCell;
|
||||
use std::option::Option;
|
||||
use adw::Leaflet;
|
||||
|
||||
use adw::prelude::*;
|
||||
use adw::subclass::prelude::*;
|
||||
use glib::once_cell::sync::OnceCell;
|
||||
use glib::subclass::InitializingObject;
|
||||
use gtk::{gio, glib, CompositeTemplate, ListBox, TemplateChild, Stack};
|
||||
use crate::ui::appview::AppView;
|
||||
|
||||
#[derive(CompositeTemplate, Default)]
|
||||
#[template(resource = "/dev/fyloz/example/window.ui")]
|
||||
pub struct Window {
|
||||
#[template_child]
|
||||
pub apps_list: TemplateChild<ListBox>,
|
||||
#[template_child]
|
||||
pub leaflet: TemplateChild<Leaflet>,
|
||||
#[template_child]
|
||||
pub stack: TemplateChild<Stack>,
|
||||
#[template_child]
|
||||
pub app_view: TemplateChild<AppView>,
|
||||
pub apps: OnceCell<gio::ListStore>,
|
||||
pub current_app: RefCell<Option<AppObject>>,
|
||||
}
|
||||
|
||||
#[glib::object_subclass]
|
||||
impl ObjectSubclass for Window {
|
||||
const NAME: &'static str = "ConfigManagerWindow";
|
||||
type Type = super::Window;
|
||||
type ParentType = adw::ApplicationWindow;
|
||||
|
||||
fn class_init(klass: &mut Self::Class) {
|
||||
klass.bind_template();
|
||||
}
|
||||
|
||||
fn instance_init(obj: &InitializingObject<Self>) {
|
||||
obj.init_template();
|
||||
}
|
||||
}
|
||||
|
||||
impl ObjectImpl for Window {
|
||||
fn constructed(&self) {
|
||||
self.parent_constructed();
|
||||
|
||||
let obj = self.obj();
|
||||
obj.setup_apps();
|
||||
obj.setup_actions();
|
||||
obj.setup_callbacks();
|
||||
obj.restore_data();
|
||||
}
|
||||
}
|
||||
|
||||
impl WidgetImpl for Window {}
|
||||
|
||||
impl WindowImpl for Window {}
|
||||
|
||||
impl ApplicationWindowImpl for Window {}
|
||||
|
||||
impl AdwApplicationWindowImpl for Window {}
|
|
@ -0,0 +1,252 @@
|
|||
mod imp;
|
||||
|
||||
use adw::{MessageDialog, NavigationDirection, ResponseAppearance};
|
||||
use crate::ui::objects::app::{AppData, AppObject};
|
||||
|
||||
use adw::prelude::*;
|
||||
use adw::subclass::prelude::*;
|
||||
use f_uuid::Uuid;
|
||||
use gtk::{gio, glib, Entry, ListBoxRow, Label, pango, SelectionMode, Button, Orientation, CenterBox};
|
||||
use glib::{clone, Object};
|
||||
|
||||
glib::wrapper! {
|
||||
pub struct Window(ObjectSubclass<imp::Window>)
|
||||
@extends adw::ApplicationWindow, gtk::Window, gtk::Widget,
|
||||
@implements gio::ActionGroup, gio::ActionMap, gtk::Accessible, gtk::Buildable,
|
||||
gtk::ConstraintTarget, gtk::Native, gtk::Root, gtk::ShortcutManager;
|
||||
}
|
||||
|
||||
impl Window {
|
||||
pub fn new(app: &adw::Application) -> Self {
|
||||
Object::builder().property("application", app).build()
|
||||
}
|
||||
|
||||
fn apps(&self) -> gio::ListStore {
|
||||
self.imp()
|
||||
.apps
|
||||
.get()
|
||||
.expect("`apps` should be set in `set_apps`.")
|
||||
.clone()
|
||||
}
|
||||
|
||||
fn create_app_row(&self, app_object: &AppObject) -> ListBoxRow {
|
||||
let label = Label::builder()
|
||||
.ellipsize(pango::EllipsizeMode::End)
|
||||
.xalign(0.0)
|
||||
.build();
|
||||
|
||||
let remove_button = Button::builder()
|
||||
.icon_name("user-trash-symbolic")
|
||||
.tooltip_text("Remove the application")
|
||||
.action_name("win.remove-application")
|
||||
.build();
|
||||
|
||||
let bbox = CenterBox::builder()
|
||||
.orientation(Orientation::Horizontal)
|
||||
.build();
|
||||
|
||||
bbox.set_start_widget(Some(&label));
|
||||
bbox.set_end_widget(Some(&remove_button));
|
||||
|
||||
self.imp().apps_list.remove(&bbox);
|
||||
|
||||
app_object
|
||||
.bind_property("name", &label, "label")
|
||||
.sync_create()
|
||||
.build();
|
||||
|
||||
ListBoxRow::builder().child(&bbox).build()
|
||||
}
|
||||
|
||||
fn current_app(&self) -> AppObject {
|
||||
self.imp()
|
||||
.current_app
|
||||
.borrow()
|
||||
.clone()
|
||||
.expect("`current_app` should be set in `set_current_app`.")
|
||||
}
|
||||
|
||||
fn new_application(&self) {
|
||||
let entry = Entry::builder()
|
||||
.placeholder_text("Name")
|
||||
.activates_default(true)
|
||||
.build();
|
||||
|
||||
let cancel_response = "cancel";
|
||||
let create_response = "create";
|
||||
|
||||
let dialog = MessageDialog::builder()
|
||||
.heading("New Application")
|
||||
.transient_for(self)
|
||||
.modal(true)
|
||||
.destroy_with_parent(true)
|
||||
.close_response(cancel_response)
|
||||
.default_response(create_response)
|
||||
.extra_child(&entry)
|
||||
.build();
|
||||
|
||||
dialog.add_responses(&[(cancel_response, "Cancel"), (create_response, "Create")]);
|
||||
dialog.set_response_enabled(create_response, false);
|
||||
dialog.set_response_appearance(create_response, ResponseAppearance::Suggested);
|
||||
|
||||
entry.connect_changed(clone!(@weak dialog => move |entry| {
|
||||
let text = entry.text();
|
||||
let empty = text.is_empty();
|
||||
|
||||
dialog.set_response_enabled(create_response, !empty);
|
||||
|
||||
if empty {
|
||||
entry.add_css_class("error");
|
||||
} else {
|
||||
entry.remove_css_class("error");
|
||||
}
|
||||
}));
|
||||
|
||||
dialog.connect_response(
|
||||
None,
|
||||
clone!(@weak self as window, @weak entry => move |dialog, response| {
|
||||
dialog.destroy();
|
||||
|
||||
if response != create_response {
|
||||
return;
|
||||
}
|
||||
|
||||
let name = entry.text().to_string();
|
||||
let app = AppObject::new(&name, "/some/path");
|
||||
|
||||
window.apps().append(&app);
|
||||
window.set_current_app(app);
|
||||
|
||||
window.imp().leaflet.navigate(NavigationDirection::Forward);
|
||||
}),
|
||||
);
|
||||
|
||||
dialog.present();
|
||||
}
|
||||
|
||||
fn remove_application(&self, id: &str) {
|
||||
let apps = self.imp().apps.get().unwrap();
|
||||
let index = apps.find_with_equal_func(|obj| -> bool {
|
||||
let id_prop = obj
|
||||
.downcast_ref::<AppObject>()
|
||||
.expect("The object should be of type 'AppObject'")
|
||||
.property_value("id");
|
||||
|
||||
let app_id = id_prop.get::<String>().expect("AppObject 'id' property should be a string");
|
||||
app_id == id
|
||||
});
|
||||
|
||||
dbg!(index);
|
||||
}
|
||||
|
||||
fn restore_data(&self) {
|
||||
let data = vec!(
|
||||
AppData {
|
||||
id: Uuid::new_random(),
|
||||
name: "IntelliJ".to_string(),
|
||||
path: "/home/william/.config/jetbrains/intellij".to_string(),
|
||||
},
|
||||
AppData {
|
||||
id: Uuid::new_random(),
|
||||
name: "Spotify".to_string(),
|
||||
path: "/home/william/.config/spotify".to_string(),
|
||||
});
|
||||
|
||||
let apps: Vec<AppObject> = data.iter()
|
||||
.map(AppObject::from_app_data)
|
||||
.collect();
|
||||
|
||||
self.apps().extend_from_slice(&apps);
|
||||
|
||||
if let Some(app) = apps.first() {
|
||||
self.set_current_app(app.clone());
|
||||
}
|
||||
}
|
||||
|
||||
fn select_app_row(&self) {
|
||||
if let Some(index) = self.apps().find(&self.current_app()) {
|
||||
let row = self.imp().apps_list.row_at_index(index as i32);
|
||||
self.imp().apps_list.select_row(row.as_ref());
|
||||
}
|
||||
}
|
||||
|
||||
fn set_current_app(&self, app: AppObject) {
|
||||
self.imp().app_view.set_application(app.clone());
|
||||
self.imp().current_app.replace(Some(app));
|
||||
self.select_app_row();
|
||||
}
|
||||
|
||||
fn set_stack(&self) {
|
||||
if self.apps().n_items() > 0 {
|
||||
self.imp().stack.set_visible_child_name("main");
|
||||
} else {
|
||||
self.imp().stack.set_visible_child_name("empty");
|
||||
}
|
||||
}
|
||||
|
||||
fn setup_actions(&self) {
|
||||
let action_new_application = gio::SimpleAction::new("new-application", None);
|
||||
action_new_application.connect_activate(clone!(@weak self as window => move |_, _| {
|
||||
window.new_application();
|
||||
}));
|
||||
self.add_action(&action_new_application);
|
||||
}
|
||||
|
||||
fn setup_apps(&self) {
|
||||
let apps = gio::ListStore::new::<AppObject>();
|
||||
self.imp()
|
||||
.apps
|
||||
.set(apps.clone())
|
||||
.expect("Could not set apps");
|
||||
|
||||
self.imp().apps_list.bind_model(
|
||||
Some(&apps),
|
||||
clone!(@weak self as window => @default-panic, move |obj| {
|
||||
let app_object = obj
|
||||
.downcast_ref()
|
||||
.expect("The object should be of type `AppObject`.");
|
||||
let row = window.create_app_row(app_object);
|
||||
row.upcast()
|
||||
}),
|
||||
)
|
||||
}
|
||||
|
||||
fn setup_callbacks(&self) {
|
||||
self.set_stack();
|
||||
self.apps().connect_items_changed(
|
||||
clone!(@weak self as window => move |_, _, _, _| {
|
||||
window.set_stack();
|
||||
})
|
||||
);
|
||||
|
||||
self.imp().apps_list.connect_row_activated(
|
||||
clone!(@weak self as window => move |_, row| {
|
||||
let index = row.index();
|
||||
let selected_app = window.apps()
|
||||
.item(index as u32)
|
||||
.expect("There needs to be an object at this position.")
|
||||
.downcast::<AppObject>()
|
||||
.expect("The object needs to be a 'AppObject'.");
|
||||
window.set_current_app(selected_app);
|
||||
window.imp().leaflet.navigate(NavigationDirection::Forward);
|
||||
})
|
||||
);
|
||||
|
||||
self.imp().leaflet.connect_folded_notify(
|
||||
clone!(@weak self as window => move |leaflet| {
|
||||
if leaflet.is_folded() {
|
||||
window
|
||||
.imp()
|
||||
.apps_list
|
||||
.set_selection_mode(SelectionMode::None)
|
||||
} else {
|
||||
window
|
||||
.imp()
|
||||
.apps_list
|
||||
.set_selection_mode(SelectionMode::Single);
|
||||
window.select_app_row();
|
||||
}
|
||||
})
|
||||
);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,65 @@
|
|||
{
|
||||
"position": "top",
|
||||
"modules-left": ["sway/workspaces"],
|
||||
"modules-right": ["network", "pulseaudio", "clock"],
|
||||
// Modules configuration
|
||||
"sway/workspaces": {
|
||||
"disable-scroll": true,
|
||||
"all-outputs": true,
|
||||
"format": "{icon}",
|
||||
"persistent_workspaces": {
|
||||
"1": [],
|
||||
"2": [],
|
||||
"3": [],
|
||||
"4": [],
|
||||
"5": [],
|
||||
"6": [],
|
||||
"7": [],
|
||||
"8": [],
|
||||
"9": [],
|
||||
"10": []
|
||||
},
|
||||
"format-icons": {
|
||||
"default": "",
|
||||
"urgent": "",
|
||||
"focused": ""
|
||||
}
|
||||
},
|
||||
"custom/spotify": {
|
||||
"format": "<span foreground='#abc123'> </span><span font='FireCodeMono Nerd Font Mono weight=325 Italic'>{}</span>",
|
||||
"interval": 1,
|
||||
"exec-if": "pgrep spotify",
|
||||
"on-click": "playerctl -p spotify play-pause",
|
||||
"on-scroll-up": "playerctl -p spotify previous",
|
||||
"on-scroll-down": "playerctl -p spotify next",
|
||||
"tooltip": false,
|
||||
"escape": true,
|
||||
"MAX-LENGTH": 60,
|
||||
"exec": "/home/loki/bin/spotify.sh"
|
||||
},
|
||||
"clock": {
|
||||
"format": "{:%a %d %H:%M} <span foreground='#123abc'></span>",
|
||||
"tooltip-format": "<big>{:%Y %B}</big>\n<tt><small>{calendar}</small></tt>"
|
||||
},
|
||||
"network": {
|
||||
"forletmat-disconnected": "Disconnected <span class='#abc123'></span>",
|
||||
"format-ethernet": "{ipaddr} <span foreground='#123abc'></span>"
|
||||
},
|
||||
"pulseaudio": {
|
||||
"format": "{volume}% <span foreground='#123abc'>{icon}</span>",
|
||||
"format-bluetooth": "{volume}% <span foreground='#abc123'>{icon}</span>",
|
||||
"format-muted": "",
|
||||
"format-icons": {
|
||||
"headphone": "",
|
||||
"hands-free": "",
|
||||
"headset": "",
|
||||
"phone": "",
|
||||
"portable": "",
|
||||
"car": "",
|
||||
"default": ["", ""]
|
||||
},
|
||||
"scroll-step": 1,
|
||||
"on-click": "pavucontrol",
|
||||
"ignored-sinks": ["Easy Effects Sink"]
|
||||
}
|
||||
}
|
|
@ -0,0 +1,65 @@
|
|||
{
|
||||
"position": "top",
|
||||
"modules-left": ["sway/workspaces"],
|
||||
"modules-right": ["network", "pulseaudio", "clock"],
|
||||
// Modules configuration
|
||||
"sway/workspaces": {
|
||||
"disable-scroll": true,
|
||||
"all-outputs": true,
|
||||
"format": "{icon}",
|
||||
"persistent_workspaces": {
|
||||
"1": [],
|
||||
"2": [],
|
||||
"3": [],
|
||||
"4": [],
|
||||
"5": [],
|
||||
"6": [],
|
||||
"7": [],
|
||||
"8": [],
|
||||
"9": [],
|
||||
"10": []
|
||||
},
|
||||
"format-icons": {
|
||||
"default": "",
|
||||
"urgent": "",
|
||||
"focused": ""
|
||||
}
|
||||
},
|
||||
"custom/spotify": {
|
||||
"format": "<span foreground='#a4b9ef'> </span><span font='FireCodeMono Nerd Font Mono weight=325 Italic'>{}</span>",
|
||||
"interval": 1,
|
||||
"exec-if": "pgrep spotify",
|
||||
"on-click": "playerctl -p spotify play-pause",
|
||||
"on-scroll-up": "playerctl -p spotify previous",
|
||||
"on-scroll-down": "playerctl -p spotify next",
|
||||
"tooltip": false,
|
||||
"escape": true,
|
||||
"MAX-LENGTH": 60,
|
||||
"exec": "/home/loki/bin/spotify.sh"
|
||||
},
|
||||
"clock": {
|
||||
"format": "{:%a %d %H:%M} <span foreground='#a4b9ef'></span>",
|
||||
"tooltip-format": "<big>{:%Y %B}</big>\n<tt><small>{calendar}</small></tt>"
|
||||
},
|
||||
"network": {
|
||||
"format-disconnected": "Disconnected <span class='#f9c096'></span>",
|
||||
"format-ethernet": "{ipaddr} <span foreground='#a4b9ef'></span>"
|
||||
},
|
||||
"pulseaudio": {
|
||||
"format": "{volume}% <span foreground='#a4b9ef'>{icon}</span>",
|
||||
"format-bluetooth": "{volume}% <span foreground='#a4b9ef'>{icon}</span>",
|
||||
"format-muted": "",
|
||||
"format-icons": {
|
||||
"headphone": "",
|
||||
"hands-free": "",
|
||||
"headset": "",
|
||||
"phone": "",
|
||||
"portable": "",
|
||||
"car": "",
|
||||
"default": ["", ""]
|
||||
},
|
||||
"scroll-step": 1,
|
||||
"on-click": "pavucontrol",
|
||||
"ignored-sinks": ["Easy Effects Sink"]
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue