diff --git a/Cargo.lock b/Cargo.lock index d00ef821..bf486ce6 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -88,7 +88,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "52bca67b61cb81e5553babde81b8211f713cb6db79766f80168f3e5f40ea6c82" dependencies = [ "ash", - "raw-window-handle", + "raw-window-handle 0.6.2", "raw-window-metal", ] @@ -103,7 +103,7 @@ dependencies = [ "enumflags2", "futures-channel", "futures-util", - "rand", + "rand 0.8.5", "serde", "serde_repr", "url", @@ -345,6 +345,29 @@ dependencies = [ "syn 2.0.66", ] +[[package]] +name = "atk" +version = "0.18.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b4af014b17dd80e8af9fa689b2d4a211ddba6eb583c1622f35d0cb543f6b17e4" +dependencies = [ + "atk-sys", + "glib", + "libc", +] + +[[package]] +name = "atk-sys" +version = "0.18.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "251e0b7d90e33e0ba930891a505a9a35ece37b2dd37a14f3ffc306c13b980009" +dependencies = [ + "glib-sys", + "gobject-sys", + "libc", + "system-deps", +] + [[package]] name = "atomic" version = "0.5.3" @@ -454,7 +477,7 @@ dependencies = [ "mint", "naga", "objc", - "raw-window-handle", + "raw-window-handle 0.6.2", "slab", "wasm-bindgen", "web-sys", @@ -566,6 +589,31 @@ version = "1.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "514de17de45fdb8dc022b1a7975556c53c86f9f0aa5f534b98977b171857c2c9" +[[package]] +name = "cairo-rs" +version = "0.18.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ca26ef0159422fb77631dc9d17b102f253b876fe1586b03b803e63a309b4ee2" +dependencies = [ + "bitflags 2.5.0", + "cairo-sys-rs", + "glib", + "libc", + "once_cell", + "thiserror", +] + +[[package]] +name = "cairo-sys-rs" +version = "0.18.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "685c9fa8e590b8b3d678873528d83411db17242a73fccaed827770ea0fedda51" +dependencies = [ + "glib-sys", + "libc", + "system-deps", +] + [[package]] name = "calloop" version = "0.13.0" @@ -598,17 +646,6 @@ version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a2698f953def977c68f935bb0dfa959375ad4638570e969e2f1e9f433cbf1af6" -[[package]] -name = "catppuccin" -version = "2.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aa1798ea21d5f88f057b9a4d075bbf3e9cc4bba98da0d6197a2019f61f633bf4" -dependencies = [ - "itertools 0.13.0", - "serde", - "serde_json", -] - [[package]] name = "cbc" version = "0.1.2" @@ -625,7 +662,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "da6bc11b07529f16944307272d5bd9b22530bc7d05751717c9d416586cedab49" dependencies = [ "clap", - "heck", + "heck 0.4.1", "indexmap 1.9.3", "log", "proc-macro2", @@ -643,6 +680,12 @@ version = "1.0.99" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "96c51067fd44124faa7f870b4b1c969379ad32b2ba805aa959430ceaa384f695" +[[package]] +name = "cesu8" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6d43a04d8753f35258c91f8ec639f792891f748a1edbd759cf1dcea3382ad83c" + [[package]] name = "cexpr" version = "0.6.0" @@ -652,6 +695,16 @@ dependencies = [ "nom", ] +[[package]] +name = "cfg-expr" +version = "0.15.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d067ad48b8650848b989a59a86c6c36a995d02d2bf778d45c3c5d57bc2718f02" +dependencies = [ + "smallvec", + "target-lexicon", +] + [[package]] name = "cfg-if" version = "1.0.0" @@ -774,6 +827,16 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3d7b894f5411737b7867f4827955924d7c254fc9f4d91a6aad6b097804b1018b" +[[package]] +name = "combine" +version = "4.6.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba5a308b75df32fe02788e748662718f03fde005016435c444eea572398219fd" +dependencies = [ + "bytes", + "memchr", +] + [[package]] name = "concurrent-queue" version = "2.5.0" @@ -804,7 +867,7 @@ version = "0.1.16" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f9d839f2a20b0aee515dc581a6172f2321f96cab76c1a38a4c584a194955390e" dependencies = [ - "getrandom", + "getrandom 0.2.15", "once_cell", "tiny-keccak", ] @@ -907,6 +970,15 @@ dependencies = [ "cfg-if", ] +[[package]] +name = "crossbeam-channel" +version = "0.5.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "33480d6946193aa8033910124896ca395333cae7e2d1113d1fef6c3272217df2" +dependencies = [ + "crossbeam-utils", +] + [[package]] name = "crossbeam-deque" version = "0.8.5" @@ -954,10 +1026,37 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" dependencies = [ "generic-array", - "rand_core", + "rand_core 0.6.4", "typenum", ] +[[package]] +name = "cssparser" +version = "0.27.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "754b69d351cdc2d8ee09ae203db831e005560fc6030da058f86ad60c92a9cb0a" +dependencies = [ + "cssparser-macros", + "dtoa-short", + "itoa 0.4.8", + "matches", + "phf 0.8.0", + "proc-macro2", + "quote", + "smallvec", + "syn 1.0.109", +] + +[[package]] +name = "cssparser-macros" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "13b588ba4ac1a99f7f2964d24b3d896ddc6bf847ee3855dbd4366f058cfcd331" +dependencies = [ + "quote", + "syn 2.0.66", +] + [[package]] name = "ctor" version = "0.2.8" @@ -1125,6 +1224,33 @@ version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "75b325c5dbd37f80359721ad39aca5a29fb04c89279657cffdda8736d0c0b9d2" +[[package]] +name = "dpi" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f25c0e292a7ca6d6498557ff1df68f32c99850012b6ea401cf8daf771f22ff53" + +[[package]] +name = "dtoa" +version = "1.0.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dcbb2bf8e87535c23f7a8a321e364ce21462d0ff10cb6407820e8e96dfff6653" + +[[package]] +name = "dtoa-short" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cd1511a7b6a56299bd043a9c167a6d2bfb37bf84a6dfceaba651168adfb43c87" +dependencies = [ + "dtoa", +] + +[[package]] +name = "dunce" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "56ce8c6da7551ec6c462cbaf3bfbc75131ebbfa1c944aeaa9dab51ca1c5f0c3b" + [[package]] name = "dwrote" version = "0.11.0" @@ -1319,6 +1445,16 @@ dependencies = [ "simd-adler32", ] +[[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 = "filedescriptor" version = "0.8.2" @@ -1610,6 +1746,100 @@ dependencies = [ "slab", ] +[[package]] +name = "fxhash" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c31b6d751ae2c7f11320402d34e41349dd1016f8d5d45e48c4312bc8625af50c" +dependencies = [ + "byteorder", +] + +[[package]] +name = "gdk" +version = "0.18.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f5ba081bdef3b75ebcdbfc953699ed2d7417d6bd853347a42a37d76406a33646" +dependencies = [ + "cairo-rs", + "gdk-pixbuf", + "gdk-sys", + "gio", + "glib", + "libc", + "pango", +] + +[[package]] +name = "gdk-pixbuf" +version = "0.18.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "50e1f5f1b0bfb830d6ccc8066d18db35c487b1b2b1e8589b5dfe9f07e8defaec" +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 = "gdk-sys" +version = "0.18.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "31ff856cb3386dae1703a920f803abafcc580e9b5f711ca62ed1620c25b51ff2" +dependencies = [ + "cairo-sys-rs", + "gdk-pixbuf-sys", + "gio-sys", + "glib-sys", + "gobject-sys", + "libc", + "pango-sys", + "pkg-config", + "system-deps", +] + +[[package]] +name = "gdkx11" +version = "0.18.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "db2ea8a4909d530f79921290389cbd7c34cb9d623bfe970eaae65ca5f9cd9cce" +dependencies = [ + "gdk", + "gdkx11-sys", + "gio", + "glib", + "libc", + "x11", +] + +[[package]] +name = "gdkx11-sys" +version = "0.18.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fee8f00f4ee46cad2939b8990f5c70c94ff882c3028f3cc5abf950fa4ab53043" +dependencies = [ + "gdk-sys", + "glib-sys", + "libc", + "system-deps", + "x11", +] + [[package]] name = "generic-array" version = "0.14.7" @@ -1630,6 +1860,17 @@ dependencies = [ "windows-targets 0.48.5", ] +[[package]] +name = "getrandom" +version = "0.1.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8fc3cb4d91f53b50155bdcfd23f6a4c39ae1969c2ae85982b135750cccaf5fce" +dependencies = [ + "cfg-if", + "libc", + "wasi 0.9.0+wasi-snapshot-preview1", +] + [[package]] name = "getrandom" version = "0.2.15" @@ -1639,7 +1880,7 @@ dependencies = [ "cfg-if", "js-sys", "libc", - "wasi", + "wasi 0.11.0+wasi-snapshot-preview1", "wasm-bindgen", ] @@ -1653,6 +1894,85 @@ dependencies = [ "weezl", ] +[[package]] +name = "gio" +version = "0.18.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d4fc8f532f87b79cbc51a79748f16a6828fb784be93145a322fa14d06d354c73" +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.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "233daaf6e83ae6a12a52055f568f9d7cf4671dabb78ff9560ab6da230ce00ee5" +dependencies = [ + "bitflags 2.5.0", + "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-macros" +version = "0.18.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0bb0228f477c0900c880fd78c8759b95c7636dbd7842707f49e132378aa2acdc" +dependencies = [ + "heck 0.4.1", + "proc-macro-crate 2.0.0", + "proc-macro-error", + "proc-macro2", + "quote", + "syn 2.0.66", +] + +[[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 = "glob" version = "0.3.1" @@ -1684,6 +2004,17 @@ dependencies = [ "web-sys", ] +[[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 = "gpu-alloc" version = "0.6.0" @@ -1752,7 +2083,7 @@ dependencies = [ "gpui_macros", "http 0.1.0", "image", - "itertools 0.11.0", + "itertools", "lazy_static", "linkme", "log", @@ -1767,8 +2098,8 @@ dependencies = [ "pathfinder_geometry", "postage", "profiling", - "rand", - "raw-window-handle", + "rand 0.8.5", + "raw-window-handle 0.6.2", "refineable", "resvg", "schemars", @@ -1817,6 +2148,58 @@ version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d196ffc1627db18a531359249b2bf8416178d84b729f3cebeb278f285fb9b58c" +[[package]] +name = "gtk" +version = "0.18.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93c4f5e0e20b60e10631a5f06da7fe3dda744b05ad0ea71fee2f47adf865890c" +dependencies = [ + "atk", + "cairo-rs", + "field-offset", + "futures-channel", + "gdk", + "gdk-pixbuf", + "gio", + "glib", + "gtk-sys", + "gtk3-macros", + "libc", + "pango", + "pkg-config", +] + +[[package]] +name = "gtk-sys" +version = "0.18.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "771437bf1de2c1c0b496c11505bdf748e26066bbe942dfc8f614c9460f6d7722" +dependencies = [ + "atk-sys", + "cairo-sys-rs", + "gdk-pixbuf-sys", + "gdk-sys", + "gio-sys", + "glib-sys", + "gobject-sys", + "libc", + "pango-sys", + "system-deps", +] + +[[package]] +name = "gtk3-macros" +version = "0.18.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c6063efb63db582968fb7df72e1ae68aa6360dcfb0a75143f34fc7d616bad75e" +dependencies = [ + "proc-macro-crate 1.3.1", + "proc-macro-error", + "proc-macro2", + "quote", + "syn 2.0.66", +] + [[package]] name = "hashbrown" version = "0.12.3" @@ -1835,6 +2218,12 @@ version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" +[[package]] +name = "heck" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" + [[package]] name = "hermit-abi" version = "0.1.19" @@ -1900,6 +2289,20 @@ dependencies = [ "windows-sys 0.52.0", ] +[[package]] +name = "html5ever" +version = "0.26.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bea68cab48b8459f17cf1c944c67ddc572d272d9f2b274140f223ecb1da4a3b7" +dependencies = [ + "log", + "mac", + "markup5ever", + "proc-macro2", + "quote", + "syn 1.0.109", +] + [[package]] name = "http" version = "0.1.0" @@ -1923,7 +2326,18 @@ checksum = "601cbb57e577e2f5ef5be8e7b83f0f63994f25aa94d673e54a92d5c516d101f1" dependencies = [ "bytes", "fnv", - "itoa", + "itoa 1.0.11", +] + +[[package]] +name = "http" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "21b9ddb458710bc376481b842f5da65cdf31522de232c1ca8146abce2a358258" +dependencies = [ + "bytes", + "fnv", + "itoa 1.0.11", ] [[package]] @@ -2193,13 +2607,10 @@ dependencies = [ ] [[package]] -name = "itertools" -version = "0.13.0" +name = "itoa" +version = "0.4.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "413ee7dfc52ee1a4949ceeb7dbc8a33f2d6c088194d9f922fb8318faf1f01186" -dependencies = [ - "either", -] +checksum = "b71991ff56294aa922b450139ee08b3bfc70982c6b2c7562771375cf73542dd4" [[package]] name = "itoa" @@ -2207,6 +2618,51 @@ version = "1.0.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b" +[[package]] +name = "javascriptcore-rs" +version = "1.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca5671e9ffce8ffba57afc24070e906da7fc4b1ba66f2cabebf61bf2ea257fcc" +dependencies = [ + "bitflags 1.3.2", + "glib", + "javascriptcore-rs-sys", +] + +[[package]] +name = "javascriptcore-rs-sys" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "af1be78d14ffa4b75b66df31840478fef72b51f8c2465d4ca7c194da9f7a5124" +dependencies = [ + "glib-sys", + "gobject-sys", + "libc", + "system-deps", +] + +[[package]] +name = "jni" +version = "0.21.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a87aa2bb7d2af34197c04845522473242e1aa17c12f4935d5856491a7fb8c97" +dependencies = [ + "cesu8", + "cfg-if", + "combine", + "jni-sys", + "log", + "thiserror", + "walkdir", + "windows-sys 0.45.0", +] + +[[package]] +name = "jni-sys" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8eaf4bc02d17cbdd7ff4c7438cafcdf7fb9a4613313ad11b4f8fefe7d3fa0130" + [[package]] name = "jpeg-decoder" version = "0.1.22" @@ -2235,6 +2691,19 @@ dependencies = [ "libloading", ] +[[package]] +name = "kuchikiki" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f29e4755b7b995046f510a7520c42b2fed58b77bd94d5a87a8eb43d2fd126da8" +dependencies = [ + "cssparser", + "html5ever", + "indexmap 1.9.3", + "matches", + "selectors", +] + [[package]] name = "kurbo" version = "0.11.0" @@ -2394,6 +2863,26 @@ dependencies = [ "libc", ] +[[package]] +name = "markup5ever" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a2629bb1404f3d34c2e921f21fd34ba00b206124c81f65c50b43b6aaefeb016" +dependencies = [ + "log", + "phf 0.10.1", + "phf_codegen 0.10.0", + "string_cache", + "string_cache_codegen", + "tendril", +] + +[[package]] +name = "matches" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2532096657941c2fea9c289d370a250971c689d4f143798ff67113ec042024a5" + [[package]] name = "md-5" version = "0.10.6" @@ -2538,7 +3027,36 @@ version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6a51313c5820b0b02bd422f4b44776fbf47961755c74ce64afc73bfad10226c3" dependencies = [ - "getrandom", + "getrandom 0.2.15", +] + +[[package]] +name = "ndk" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "451422b7e4718271c8b5b3aadf5adedba43dc76312454b387e98fae0fc951aa0" +dependencies = [ + "bitflags 1.3.2", + "jni-sys", + "ndk-sys", + "num_enum", + "raw-window-handle 0.5.2", + "thiserror", +] + +[[package]] +name = "ndk-context" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "27b02d87554356db9e9a873add8782d4ea6e3e58ea071a9adb9a2e8ddb884a8b" + +[[package]] +name = "ndk-sys" +version = "0.4.1+23.1.7779620" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3cf2aae958bd232cac5069850591667ad422d263686d75b52a065f9badeee5a3" +dependencies = [ + "jni-sys", ] [[package]] @@ -2560,6 +3078,12 @@ dependencies = [ "memoffset", ] +[[package]] +name = "nodrop" +version = "0.1.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72ef4a56884ca558e5ddb05a1d1e7e1bfd9a68d9ed024c21704cc98872dae1bb" + [[package]] name = "nom" version = "7.1.3" @@ -2606,7 +3130,7 @@ dependencies = [ "num-integer", "num-iter", "num-traits", - "rand", + "rand 0.8.5", "serde", "smallvec", "zeroize", @@ -2688,6 +3212,27 @@ dependencies = [ "libc", ] +[[package]] +name = "num_enum" +version = "0.5.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1f646caf906c20226733ed5b1374287eb97e3c2a5c227ce668c1f2ce20ae57c9" +dependencies = [ + "num_enum_derive", +] + +[[package]] +name = "num_enum_derive" +version = "0.5.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dcbff9bc912032c62bf65ef1d5aea88983b420f4f839db1e9b0c281a25c9c799" +dependencies = [ + "proc-macro-crate 1.3.1", + "proc-macro2", + "quote", + "syn 1.0.109", +] + [[package]] name = "objc" version = "0.2.7" @@ -2707,6 +3252,15 @@ dependencies = [ "cc", ] +[[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" @@ -2736,7 +3290,7 @@ dependencies = [ "num", "num-bigint-dig", "pbkdf2", - "rand", + "rand 0.8.5", "serde", "sha2", "subtle", @@ -2790,6 +3344,31 @@ version = "6.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e2355d85b9a3786f481747ced0e0ff2ba35213a1f9bd406ed906554d7af805a1" +[[package]] +name = "pango" +version = "0.18.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ca27ec1eb0457ab26f3036ea52229edbdb74dee1edd29063f5b9b010e7ebee4" +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 = "parking" version = "2.2.0" @@ -2872,6 +3451,98 @@ version = "2.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" +[[package]] +name = "phf" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3dfb61232e34fcb633f43d12c58f83c1df82962dcdfa565a4e866ffc17dafe12" +dependencies = [ + "phf_macros", + "phf_shared 0.8.0", + "proc-macro-hack", +] + +[[package]] +name = "phf" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fabbf1ead8a5bcbc20f5f8b939ee3f5b0f6f281b6ad3468b84656b658b455259" +dependencies = [ + "phf_shared 0.10.0", +] + +[[package]] +name = "phf_codegen" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cbffee61585b0411840d3ece935cce9cb6321f01c45477d30066498cd5e1a815" +dependencies = [ + "phf_generator 0.8.0", + "phf_shared 0.8.0", +] + +[[package]] +name = "phf_codegen" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4fb1c3a8bc4dd4e5cfce29b44ffc14bedd2ee294559a294e2a4d4c9e9a6a13cd" +dependencies = [ + "phf_generator 0.10.0", + "phf_shared 0.10.0", +] + +[[package]] +name = "phf_generator" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "17367f0cc86f2d25802b2c26ee58a7b23faeccf78a396094c13dced0d0182526" +dependencies = [ + "phf_shared 0.8.0", + "rand 0.7.3", +] + +[[package]] +name = "phf_generator" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5d5285893bb5eb82e6aaf5d59ee909a06a16737a8970984dd7746ba9283498d6" +dependencies = [ + "phf_shared 0.10.0", + "rand 0.8.5", +] + +[[package]] +name = "phf_macros" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f6fde18ff429ffc8fe78e2bf7f8b7a5a5a6e2a8b58bc5a9ac69198bbda9189c" +dependencies = [ + "phf_generator 0.8.0", + "phf_shared 0.8.0", + "proc-macro-hack", + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "phf_shared" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c00cf8b9eafe68dde5e9eaa2cef8ee84a9336a47d566ec55ca16589633b65af7" +dependencies = [ + "siphasher 0.3.11", +] + +[[package]] +name = "phf_shared" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6796ad771acdc0123d2a88dc428b5e38ef24456743ddb1744ed628f9815c096" +dependencies = [ + "siphasher 0.3.11", +] + [[package]] name = "pico-args" version = "0.5.0" @@ -3018,6 +3689,12 @@ version = "0.2.17" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" +[[package]] +name = "precomputed-hash" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "925383efa346730478fb4838dbe9137d2a47675ad789c546d150a6e1dd4ab31c" + [[package]] name = "prettyplease" version = "0.2.20" @@ -3028,6 +3705,25 @@ dependencies = [ "syn 2.0.66", ] +[[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 0.19.15", +] + +[[package]] +name = "proc-macro-crate" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7e8366a6159044a37876a2b9817124296703c586a5c92e2c53751fa06d8d43e8" +dependencies = [ + "toml_edit 0.20.7", +] + [[package]] name = "proc-macro-crate" version = "3.1.0" @@ -3037,6 +3733,36 @@ dependencies = [ "toml_edit 0.21.1", ] +[[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-macro-hack" +version = "0.5.20+deprecated" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc375e1527247fe1a97d8b7156678dfe7c1af2fc075c9a4db3690ecd2a148068" + [[package]] name = "proc-macro2" version = "1.0.85" @@ -3083,6 +3809,20 @@ dependencies = [ "proc-macro2", ] +[[package]] +name = "rand" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a6b1679d49b24bbfe0c803429aa1874472f50d9b363131f0e89fc356b544d03" +dependencies = [ + "getrandom 0.1.16", + "libc", + "rand_chacha 0.2.2", + "rand_core 0.5.1", + "rand_hc", + "rand_pcg", +] + [[package]] name = "rand" version = "0.8.5" @@ -3090,8 +3830,18 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" dependencies = [ "libc", - "rand_chacha", - "rand_core", + "rand_chacha 0.3.1", + "rand_core 0.6.4", +] + +[[package]] +name = "rand_chacha" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f4c8ed856279c9737206bf725bf36935d8666ead7aa69b52be55af369d193402" +dependencies = [ + "ppv-lite86", + "rand_core 0.5.1", ] [[package]] @@ -3101,7 +3851,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" dependencies = [ "ppv-lite86", - "rand_core", + "rand_core 0.6.4", +] + +[[package]] +name = "rand_core" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19" +dependencies = [ + "getrandom 0.1.16", ] [[package]] @@ -3110,7 +3869,25 @@ version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" dependencies = [ - "getrandom", + "getrandom 0.2.15", +] + +[[package]] +name = "rand_hc" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca3129af7b92a17112d59ad498c6f81eaf463253766b90396d39ea7a39d6613c" +dependencies = [ + "rand_core 0.5.1", +] + +[[package]] +name = "rand_pcg" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "16abd0c1b639e9eb4d7c50c0b8100b0d0f849be2349829c740fe8e6eb4816429" +dependencies = [ + "rand_core 0.5.1", ] [[package]] @@ -3119,6 +3896,12 @@ version = "1.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f60fcc7d6849342eff22c4350c8b9a989ee8ceabc4b481253e8946b9fe83d684" +[[package]] +name = "raw-window-handle" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f2ff9a1f06a88b01621b7ae906ef0211290d1c8a168a15542486a8f61c0833b9" + [[package]] name = "raw-window-handle" version = "0.6.2" @@ -3134,7 +3917,7 @@ dependencies = [ "cocoa", "core-graphics", "objc", - "raw-window-handle", + "raw-window-handle 0.6.2", ] [[package]] @@ -3182,7 +3965,7 @@ version = "0.4.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bd283d9651eeda4b2a83a43c1c91b266c40fd76ecd39a50a8c630ae69dc72891" dependencies = [ - "getrandom", + "getrandom 0.2.15", "libredox", "thiserror", ] @@ -3419,6 +4202,26 @@ version = "4.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1c107b6f4780854c8b126e228ea8869f4d7b71260f962fefb57b996b8959ba6b" +[[package]] +name = "selectors" +version = "0.22.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df320f1889ac4ba6bc0cdc9c9af7af4bd64bb927bccdf32d81140dc1f9be12fe" +dependencies = [ + "bitflags 1.3.2", + "cssparser", + "derive_more", + "fxhash", + "log", + "matches", + "phf 0.8.0", + "phf_codegen 0.8.0", + "precomputed-hash", + "servo_arc", + "smallvec", + "thin-slice", +] + [[package]] name = "self_cell" version = "1.0.4" @@ -3487,7 +4290,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "455182ea6142b14f93f4bc5320a2b31c1f266b66a4a5c858b013302a5d8cbfc3" dependencies = [ "indexmap 2.2.6", - "itoa", + "itoa 1.0.11", "ryu", "serde", ] @@ -3512,6 +4315,16 @@ dependencies = [ "serde", ] +[[package]] +name = "servo_arc" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d98238b800e0d1576d8b6e3de32827c2d74bee68bb97748dcf5071fb53965432" +dependencies = [ + "nodrop", + "stable_deref_trait", +] + [[package]] name = "sha1" version = "0.10.6" @@ -3570,6 +4383,12 @@ dependencies = [ "log", ] +[[package]] +name = "siphasher" +version = "0.3.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38b58827f4464d87d377d175e90bf58eb00fd8716ff0a62f80356b5e61555d0d" + [[package]] name = "siphasher" version = "1.0.1" @@ -3648,6 +4467,32 @@ dependencies = [ "windows-sys 0.52.0", ] +[[package]] +name = "soup3" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "471f924a40f31251afc77450e781cb26d55c0b650842efafc9c6cbd2f7cc4f9f" +dependencies = [ + "futures-channel", + "gio", + "glib", + "libc", + "soup3-sys", +] + +[[package]] +name = "soup3-sys" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ebe8950a680a12f24f15ebe1bf70db7af98ad242d9db43596ad3108aab86c27" +dependencies = [ + "gio-sys", + "glib-sys", + "gobject-sys", + "libc", + "system-deps", +] + [[package]] name = "spin" version = "0.5.2" @@ -3694,6 +4539,32 @@ dependencies = [ "float-cmp", ] +[[package]] +name = "string_cache" +version = "0.8.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f91138e76242f575eb1d3b38b4f1362f10d3a43f47d182a5b359af488a02293b" +dependencies = [ + "new_debug_unreachable", + "once_cell", + "parking_lot", + "phf_shared 0.10.0", + "precomputed-hash", + "serde", +] + +[[package]] +name = "string_cache_codegen" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6bb30289b722be4ff74a408c3cc27edeaad656e06cb1fe8fa9231fa59c728988" +dependencies = [ + "phf_generator 0.10.0", + "phf_shared 0.10.0", + "proc-macro2", + "quote", +] + [[package]] name = "strsim" version = "0.10.0" @@ -3747,7 +4618,7 @@ version = "2.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c4e188677497de274a1367c4bda15bd2296de4070d91729aac8f0a09c1abf64d" dependencies = [ - "itoa", + "itoa 1.0.11", "ryu", "sval", ] @@ -3758,7 +4629,7 @@ version = "2.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "32f456c07dae652744781f2245d5e3b78e6a9ebad70790ac11eb15dbdbce5282" dependencies = [ - "itoa", + "itoa 1.0.11", "ryu", "sval", ] @@ -3807,7 +4678,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fae3064df9b89391c9a76a0425a69d124aee9c5c28455204709e72c39868a43c" dependencies = [ "kurbo", - "siphasher", + "siphasher 1.0.1", ] [[package]] @@ -3863,6 +4734,19 @@ dependencies = [ "libc", ] +[[package]] +name = "system-deps" +version = "6.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a3e535eb8dded36d55ec13eddacd30dec501792ff23a0b1682c38601b8cf2349" +dependencies = [ + "cfg-expr", + "heck 0.5.0", + "pkg-config", + "toml 0.8.14", + "version-compare", +] + [[package]] name = "taffy" version = "0.4.4" @@ -3882,6 +4766,23 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8bdb6fa0dfa67b38c1e66b7041ba9dcf23b99d8121907cd31c807a332f7a0bbb" +[[package]] +name = "tao-macros" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec114582505d158b669b136e6851f85840c109819d77c42bb7c0709f727d18c2" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "target-lexicon" +version = "0.12.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e1fc403891a21bcfb7c37834ba66a547a8f402146eba7265b5a6d88059c9ff2f" + [[package]] name = "tempfile" version = "3.10.1" @@ -3920,6 +4821,12 @@ version = "0.16.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "23d434d3f8967a09480fb04132ebe0a3e088c173e6d0ee7897abbdf4eab0f8b9" +[[package]] +name = "thin-slice" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8eaa81235c7058867fa8c0e7314f33dcce9c215f535d1913822a2b3f5e289f3c" + [[package]] name = "thiserror" version = "1.0.61" @@ -3958,7 +4865,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5dfd88e563464686c916c7e46e623e520ddc6d79fa6641390f2e3fa86e83e885" dependencies = [ "deranged", - "itoa", + "itoa 1.0.11", "num-conv", "powerfmt", "serde", @@ -4072,6 +4979,28 @@ dependencies = [ "serde", ] +[[package]] +name = "toml_edit" +version = "0.19.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b5bb770da30e5cbfde35a2d7b9b8a2c4b8ef89548a7a6aeab5c9a576e3e7421" +dependencies = [ + "indexmap 2.2.6", + "toml_datetime", + "winnow 0.5.40", +] + +[[package]] +name = "toml_edit" +version = "0.20.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "70f427fce4d84c72b5b732388bf4a9f4531b53f74e2887e3ecb2481f68f66d81" +dependencies = [ + "indexmap 2.2.6", + "toml_datetime", + "winnow 0.5.40", +] + [[package]] name = "toml_edit" version = "0.21.1" @@ -4172,13 +5101,14 @@ name = "ui" version = "0.1.0" dependencies = [ "anyhow", - "catppuccin", "gpui", "log", "serde", "serde_json", "smallvec", + "unicode-segmentation", "windows", + "wry", ] [[package]] @@ -4285,7 +5215,7 @@ dependencies = [ "pico-args", "roxmltree", "simplecss", - "siphasher", + "siphasher 1.0.1", "strict-num", "svgtypes", "tiny-skia-path", @@ -4330,7 +5260,7 @@ dependencies = [ "futures-lite 1.13.0", "globset", "log", - "rand", + "rand 0.8.5", "regex", "rust-embed", "serde", @@ -4346,7 +5276,7 @@ version = "1.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a183cf7feeba97b4dd1c0d46788634f6221d87fa961b305bed08c851829efcc0" dependencies = [ - "getrandom", + "getrandom 0.2.15", "serde", "sha1_smol", ] @@ -4393,6 +5323,12 @@ version = "0.2.15" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" +[[package]] +name = "version-compare" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "852e951cb7832cb45cb1169900d19760cfa39b82bc0ea9c0e5a14ae88411c98b" + [[package]] name = "version_check" version = "0.9.4" @@ -4435,6 +5371,12 @@ dependencies = [ "winapi-util", ] +[[package]] +name = "wasi" +version = "0.9.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519" + [[package]] name = "wasi" version = "0.11.0+wasi-snapshot-preview1" @@ -4590,6 +5532,86 @@ dependencies = [ "wasm-bindgen", ] +[[package]] +name = "webkit2gtk" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "76b1bc1e54c581da1e9f179d0b38512ba358fb1af2d634a1affe42e37172361a" +dependencies = [ + "bitflags 1.3.2", + "cairo-rs", + "gdk", + "gdk-sys", + "gio", + "gio-sys", + "glib", + "glib-sys", + "gobject-sys", + "gtk", + "gtk-sys", + "javascriptcore-rs", + "libc", + "once_cell", + "soup3", + "webkit2gtk-sys", +] + +[[package]] +name = "webkit2gtk-sys" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62daa38afc514d1f8f12b8693d30d5993ff77ced33ce30cd04deebc267a6d57c" +dependencies = [ + "bitflags 1.3.2", + "cairo-sys-rs", + "gdk-sys", + "gio-sys", + "glib-sys", + "gobject-sys", + "gtk-sys", + "javascriptcore-rs-sys", + "libc", + "pkg-config", + "soup3-sys", + "system-deps", +] + +[[package]] +name = "webview2-com" +version = "0.31.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6516cfa64c6b3212686080eeec378e662c2af54bb2a5b2a22749673f5cb2226f" +dependencies = [ + "webview2-com-macros", + "webview2-com-sys", + "windows", + "windows-core", + "windows-implement", + "windows-interface", +] + +[[package]] +name = "webview2-com-macros" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac1345798ecd8122468840bcdf1b95e5dc6d2206c5e4b0eafa078d061f59c9bc" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.66", +] + +[[package]] +name = "webview2-com-sys" +version = "0.31.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c76d5b77320ff155660be1df3e6588bc85c75f1a9feef938cc4dc4dd60d1d7cf" +dependencies = [ + "thiserror", + "windows", + "windows-core", +] + [[package]] name = "weezl" version = "0.1.8" @@ -4692,6 +5714,15 @@ dependencies = [ "windows-targets 0.52.5", ] +[[package]] +name = "windows-sys" +version = "0.45.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75283be5efb2831d37ea142365f009c02ec203cd29a3ebecbc093d52315b66d0" +dependencies = [ + "windows-targets 0.42.2", +] + [[package]] name = "windows-sys" version = "0.48.0" @@ -4710,6 +5741,21 @@ dependencies = [ "windows-targets 0.52.5", ] +[[package]] +name = "windows-targets" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e5180c00cd44c9b1c88adb3693291f1cd93605ded80c250a75d472756b4d071" +dependencies = [ + "windows_aarch64_gnullvm 0.42.2", + "windows_aarch64_msvc 0.42.2", + "windows_i686_gnu 0.42.2", + "windows_i686_msvc 0.42.2", + "windows_x86_64_gnu 0.42.2", + "windows_x86_64_gnullvm 0.42.2", + "windows_x86_64_msvc 0.42.2", +] + [[package]] name = "windows-targets" version = "0.48.5" @@ -4741,6 +5787,21 @@ dependencies = [ "windows_x86_64_msvc 0.52.5", ] +[[package]] +name = "windows-version" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6998aa457c9ba8ff2fb9f13e9d2a930dabcea28f1d0ab94d687d8b3654844515" +dependencies = [ + "windows-targets 0.52.5", +] + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "597a5118570b68bc08d8d59125332c54f1ba9d9adeedeef5b99b02ba2b0698f8" + [[package]] name = "windows_aarch64_gnullvm" version = "0.48.5" @@ -4753,6 +5814,12 @@ version = "0.52.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7088eed71e8b8dda258ecc8bac5fb1153c5cffaf2578fc8ff5d61e23578d3263" +[[package]] +name = "windows_aarch64_msvc" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e08e8864a60f06ef0d0ff4ba04124db8b0fb3be5776a5cd47641e942e58c4d43" + [[package]] name = "windows_aarch64_msvc" version = "0.48.5" @@ -4765,6 +5832,12 @@ version = "0.52.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9985fd1504e250c615ca5f281c3f7a6da76213ebd5ccc9561496568a2752afb6" +[[package]] +name = "windows_i686_gnu" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c61d927d8da41da96a81f029489353e68739737d3beca43145c8afec9a31a84f" + [[package]] name = "windows_i686_gnu" version = "0.48.5" @@ -4783,6 +5856,12 @@ version = "0.52.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "87f4261229030a858f36b459e748ae97545d6f1ec60e5e0d6a3d32e0dc232ee9" +[[package]] +name = "windows_i686_msvc" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "44d840b6ec649f480a41c8d80f9c65108b92d89345dd94027bfe06ac444d1060" + [[package]] name = "windows_i686_msvc" version = "0.48.5" @@ -4795,6 +5874,12 @@ version = "0.52.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "db3c2bf3d13d5b658be73463284eaf12830ac9a26a90c717b7f771dfe97487bf" +[[package]] +name = "windows_x86_64_gnu" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8de912b8b8feb55c064867cf047dda097f92d51efad5b491dfb98f6bbb70cb36" + [[package]] name = "windows_x86_64_gnu" version = "0.48.5" @@ -4807,6 +5892,12 @@ version = "0.52.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4e4246f76bdeff09eb48875a0fd3e2af6aada79d409d33011886d3e1581517d9" +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26d41b46a36d453748aedef1486d5c7a85db22e56aff34643984ea85514e94a3" + [[package]] name = "windows_x86_64_gnullvm" version = "0.48.5" @@ -4819,6 +5910,12 @@ version = "0.52.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "852298e482cd67c356ddd9570386e2862b5673c85bd5f88df9ab6802b334c596" +[[package]] +name = "windows_x86_64_msvc" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9aec5da331524158c6d1a4ac0ab1541149c0b9505fde06423b02f5ef0106b9f0" + [[package]] name = "windows_x86_64_msvc" version = "0.48.5" @@ -4891,6 +5988,58 @@ version = "0.5.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1e9df38ee2d2c3c5948ea468a8406ff0db0b29ae1ffde1bcf20ef305bcc95c51" +[[package]] +name = "wry" +version = "0.41.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68b00c945786b02d7805d09a969fa36d0eee4e0bd4fb3ec2a79d2bf45a1b44cd" +dependencies = [ + "base64", + "block", + "cocoa", + "core-graphics", + "crossbeam-channel", + "dpi", + "dunce", + "gdkx11", + "gtk", + "html5ever", + "http 1.1.0", + "javascriptcore-rs", + "jni", + "kuchikiki", + "libc", + "ndk", + "ndk-context", + "ndk-sys", + "objc", + "objc_id", + "once_cell", + "percent-encoding", + "raw-window-handle 0.6.2", + "sha2", + "soup3", + "tao-macros", + "thiserror", + "webkit2gtk", + "webkit2gtk-sys", + "webview2-com", + "windows", + "windows-core", + "windows-version", + "x11-dl", +] + +[[package]] +name = "x11" +version = "2.21.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "502da5464ccd04011667b11c435cb992822c2c0dbde1770c988480d312a0db2e" +dependencies = [ + "libc", + "pkg-config", +] + [[package]] name = "x11-clipboard" version = "0.9.2" @@ -4901,6 +6050,17 @@ dependencies = [ "x11rb", ] +[[package]] +name = "x11-dl" +version = "2.21.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38735924fedd5314a6e548792904ed8c6de6636285cb9fec04d5b1db85c1516f" +dependencies = [ + "libc", + "once_cell", + "pkg-config", +] + [[package]] name = "x11rb" version = "0.13.1" @@ -5055,7 +6215,7 @@ dependencies = [ "hex", "nix", "ordered-stream", - "rand", + "rand 0.8.5", "serde", "serde_repr", "sha1", @@ -5075,7 +6235,7 @@ version = "4.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6fe9de53245dcf426b7be226a4217dd5e339080e5d46e64a02d6e5dcbf90fca1" dependencies = [ - "proc-macro-crate", + "proc-macro-crate 3.1.0", "proc-macro2", "quote", "syn 2.0.66", @@ -5202,7 +6362,7 @@ version = "4.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "642bf1b6b6d527988b3e8193d20969d53700a36eac734d21ae6639db168701c8" dependencies = [ - "proc-macro-crate", + "proc-macro-crate 3.1.0", "proc-macro2", "quote", "syn 2.0.66", diff --git a/crates/ui-story/src/input_story.rs b/crates/ui-story/src/input_story.rs index 03eae973..1c0905c3 100644 --- a/crates/ui-story/src/input_story.rs +++ b/crates/ui-story/src/input_story.rs @@ -3,27 +3,27 @@ use gpui::{ VisualContext, WindowContext, }; -use ui::text_field::TextField; +use ui::input::TextInput; use super::story_case; pub struct InputStory { - input1: View, - input2: View, - mash_input: View, - disabled_input: View, + input1: View, + input2: View, + mash_input: View, + disabled_input: View, } impl InputStory { pub(crate) fn new(cx: &mut WindowContext) -> Self { let input1 = cx.new_view(|cx| { - let mut input = TextField::new(cx); + let mut input = TextInput::new(cx); input.set_text("Hello 世界", cx); input }); let mask_input = cx.new_view(|cx| { - let mut input = TextField::new(cx); + let mut input = TextInput::new(cx); input.set_masked(true, cx); input.set_text("this-is-password", cx); input @@ -32,13 +32,13 @@ impl InputStory { Self { input1, input2: cx.new_view(|cx| { - let mut input = TextField::new(cx); + let mut input = TextInput::new(cx); input.set_placeholder("Enter text here...", cx); input }), mash_input: mask_input, disabled_input: cx.new_view(|cx| { - let mut input = TextField::new(cx); + let mut input = TextInput::new(cx); input.set_text("This is disabled input", cx); input.set_disabled(true, cx); input diff --git a/crates/ui/Cargo.toml b/crates/ui/Cargo.toml index 4860157d..8e72d78c 100644 --- a/crates/ui/Cargo.toml +++ b/crates/ui/Cargo.toml @@ -12,3 +12,4 @@ serde_json = "1" wry = "0" smallvec = "1.13.2" windows = "0.57.0" +unicode-segmentation = "1.11.0" \ No newline at end of file diff --git a/crates/ui/src/event.rs b/crates/ui/src/event.rs new file mode 100644 index 00000000..81abcb82 --- /dev/null +++ b/crates/ui/src/event.rs @@ -0,0 +1,28 @@ +use gpui::{ClickEvent, Element, Focusable, InteractiveElement, Stateful, WindowContext}; + +pub trait InterativeElementExt: InteractiveElement { + /// Set the listener for a double click event. + fn on_double_click( + mut self, + listener: impl Fn(&ClickEvent, &mut WindowContext) + 'static, + ) -> Self + where + Self: Sized, + { + self.interactivity().on_click(move |event, context| { + if event.up.click_count == 2 { + listener(event, context); + } + }); + self + } +} + +impl InterativeElementExt for Focusable {} + +// impl InterativeElementExt for Stateful +// where +// E: Element, +// Self: InteractiveElement, +// { +// } diff --git a/crates/ui/src/input.rs b/crates/ui/src/input.rs new file mode 100644 index 00000000..eb1a441e --- /dev/null +++ b/crates/ui/src/input.rs @@ -0,0 +1,602 @@ +use std::ops::Range; + +use crate::event::InterativeElementExt as _; +use crate::theme::ActiveTheme; +use gpui::*; +use prelude::FluentBuilder as _; +use unicode_segmentation::*; + +actions!( + text_input, + [ + Backspace, + Delete, + Left, + Right, + SelectLeft, + SelectRight, + SelectAll, + Home, + End, + ShowCharacterPalette, + Copy, + Cut, + Paste, + MoveToStartOfLine, + MoveToEndOfLine, + ] +); + +pub fn init(cx: &mut AppContext) { + cx.bind_keys([ + KeyBinding::new("backspace", Backspace, None), + KeyBinding::new("delete", Delete, None), + KeyBinding::new("left", Left, None), + KeyBinding::new("right", Right, None), + KeyBinding::new("shift-left", SelectLeft, None), + KeyBinding::new("shift-right", SelectRight, None), + KeyBinding::new("cmd-a", SelectAll, None), + KeyBinding::new("home", Home, None), + KeyBinding::new("end", End, None), + KeyBinding::new("ctrl-cmd-space", ShowCharacterPalette, None), + KeyBinding::new("cmd-c", Copy, None), + KeyBinding::new("cmd-x", Cut, None), + KeyBinding::new("cmd-v", Paste, None), + KeyBinding::new("ctrl-a", MoveToStartOfLine, None), + KeyBinding::new("ctrl-e", MoveToEndOfLine, None), + ]); +} + +pub struct TextInput { + focus_handle: FocusHandle, + text: SharedString, + placeholder: SharedString, + selected_range: Range, + selection_reversed: bool, + marked_range: Option>, + last_layout: Option, + disabled: bool, + masked: bool, + appearance: bool, +} + +impl TextInput { + pub fn new(cx: &mut ViewContext) -> Self { + Self { + focus_handle: cx.focus_handle(), + text: "".into(), + placeholder: "".into(), + selected_range: 0..0, + selection_reversed: false, + marked_range: None, + last_layout: None, + disabled: false, + masked: false, + appearance: true, + } + } + + /// Set the text of the input field. + pub fn set_text(&mut self, text: impl Into, cx: &mut ViewContext) { + self.text = text.into(); + self.selected_range = self.text.len()..self.text.len(); + cx.notify(); + } + + /// Set the placeholder text of the input field. + pub fn set_placeholder( + &mut self, + placeholder: impl Into, + cx: &mut ViewContext, + ) { + self.placeholder = placeholder.into(); + cx.notify(); + } + + /// Set the disabled state of the input field. + pub fn set_disabled(&mut self, disabled: bool, cx: &mut ViewContext) { + self.disabled = disabled; + cx.notify(); + } + + /// Set the masked state of the input field. + pub fn set_masked(&mut self, masked: bool, cx: &mut ViewContext) { + self.masked = masked; + cx.notify(); + } + + /// Set the appearance of the input field. + pub fn appearance(mut self, appearance: bool) -> Self { + self.appearance = appearance; + self + } + + /// Return the text of the input field. + pub fn text(&self) -> SharedString { + self.text.clone() + } + + fn left(&mut self, _: &Left, cx: &mut ViewContext) { + if self.selected_range.is_empty() { + self.move_to(self.previous_boundary(self.cursor_offset()), cx); + } else { + self.move_to(self.selected_range.start, cx) + } + } + + fn right(&mut self, _: &Right, cx: &mut ViewContext) { + if self.selected_range.is_empty() { + self.move_to(self.next_boundary(self.selected_range.end), cx); + } else { + self.move_to(self.selected_range.end, cx) + } + } + + fn select_left(&mut self, _: &SelectLeft, cx: &mut ViewContext) { + self.select_to(self.previous_boundary(self.cursor_offset()), cx); + } + + fn select_right(&mut self, _: &SelectRight, cx: &mut ViewContext) { + self.select_to(self.next_boundary(self.cursor_offset()), cx); + } + + fn select_all(&mut self, _: &SelectAll, cx: &mut ViewContext) { + self.move_to(0, cx); + self.select_to(self.text.len(), cx) + } + + fn home(&mut self, _: &Home, cx: &mut ViewContext) { + self.move_to(0, cx); + } + + fn end(&mut self, _: &End, cx: &mut ViewContext) { + self.move_to(self.text.len(), cx); + } + + fn backspace(&mut self, _: &Backspace, cx: &mut ViewContext) { + if self.selected_range.is_empty() { + self.select_to(self.previous_boundary(self.cursor_offset()), cx) + } + self.replace_text_in_range(None, "", cx) + } + + fn delete(&mut self, _: &Delete, cx: &mut ViewContext) { + if self.selected_range.is_empty() { + self.select_to(self.next_boundary(self.cursor_offset()), cx) + } + self.replace_text_in_range(None, "", cx) + } + + fn show_character_palette(&mut self, _: &ShowCharacterPalette, cx: &mut ViewContext) { + cx.show_character_palette(); + } + + fn copy(&mut self, _: &Copy, cx: &mut ViewContext) { + let selected_text = self.text[self.selected_range.clone()].to_string(); + cx.write_to_clipboard(ClipboardItem::new(selected_text)); + } + + fn cut(&mut self, _: &Cut, cx: &mut ViewContext) { + let selected_text = self.text[self.selected_range.clone()].to_string(); + cx.write_to_clipboard(ClipboardItem::new(selected_text)); + self.replace_text_in_range(Some(self.selected_range.clone()), "", cx); + } + + pub fn paste(&mut self, _: &Paste, cx: &mut ViewContext) { + if let Some(clipboard) = cx.read_from_clipboard() { + self.replace_text_in_range(Some(self.selected_range.clone()), clipboard.text(), cx); + } + } + + fn move_to_start_of_line(&mut self, _: &MoveToStartOfLine, cx: &mut ViewContext) { + self.move_to(0, cx); + } + + fn move_to_end_of_line(&mut self, _: &MoveToEndOfLine, cx: &mut ViewContext) { + self.move_to(self.text.len(), cx); + } + + fn move_to(&mut self, offset: usize, cx: &mut ViewContext) { + self.selected_range = offset..offset; + cx.notify() + } + + fn cursor_offset(&self) -> usize { + if self.selection_reversed { + self.selected_range.start + } else { + self.selected_range.end + } + } + + fn select_to(&mut self, offset: usize, cx: &mut ViewContext) { + if self.selection_reversed { + self.selected_range.start = offset + } else { + self.selected_range.end = offset + }; + if self.selected_range.end < self.selected_range.start { + self.selection_reversed = !self.selection_reversed; + self.selected_range = self.selected_range.end..self.selected_range.start; + } + cx.notify() + } + + fn offset_from_utf16(&self, offset: usize) -> usize { + let mut utf8_offset = 0; + let mut utf16_count = 0; + + for ch in self.text.chars() { + if utf16_count >= offset { + break; + } + utf16_count += ch.len_utf16(); + utf8_offset += ch.len_utf8(); + } + + utf8_offset + } + + fn offset_to_utf16(&self, offset: usize) -> usize { + let mut utf16_offset = 0; + let mut utf8_count = 0; + + for ch in self.text.chars() { + if utf8_count >= offset { + break; + } + utf8_count += ch.len_utf8(); + utf16_offset += ch.len_utf16(); + } + + utf16_offset + } + + fn range_to_utf16(&self, range: &Range) -> Range { + self.offset_to_utf16(range.start)..self.offset_to_utf16(range.end) + } + + fn range_from_utf16(&self, range_utf16: &Range) -> Range { + self.offset_from_utf16(range_utf16.start)..self.offset_from_utf16(range_utf16.end) + } + + fn previous_boundary(&self, offset: usize) -> usize { + self.text + .grapheme_indices(true) + .rev() + .find_map(|(idx, _)| (idx < offset).then_some(idx)) + .unwrap_or(0) + } + + fn next_boundary(&self, offset: usize) -> usize { + self.text + .grapheme_indices(true) + .find_map(|(idx, _)| (idx > offset).then_some(idx)) + .unwrap_or(self.text.len()) + } +} + +impl ViewInputHandler for TextInput { + fn text_for_range( + &mut self, + range_utf16: Range, + _cx: &mut ViewContext, + ) -> Option { + let range = self.range_from_utf16(&range_utf16); + Some(self.text[range].to_string()) + } + + fn selected_text_range(&mut self, _cx: &mut ViewContext) -> Option> { + Some(self.range_to_utf16(&self.selected_range)) + } + + fn marked_text_range(&self, _cx: &mut ViewContext) -> Option> { + self.marked_range + .as_ref() + .map(|range| self.range_to_utf16(range)) + } + + fn unmark_text(&mut self, _cx: &mut ViewContext) { + self.marked_range = None; + } + + fn replace_text_in_range( + &mut self, + range_utf16: Option>, + new_text: &str, + cx: &mut ViewContext, + ) { + let range = range_utf16 + .as_ref() + .map(|range_utf16| self.range_from_utf16(range_utf16)) + .or(self.marked_range.clone()) + .unwrap_or(self.selected_range.clone()); + + self.text = + (self.text[0..range.start].to_owned() + new_text + &self.text[range.end..]).into(); + self.selected_range = range.start + new_text.len()..range.start + new_text.len(); + self.marked_range.take(); + cx.notify(); + } + + fn replace_and_mark_text_in_range( + &mut self, + range_utf16: Option>, + new_text: &str, + new_selected_range_utf16: Option>, + cx: &mut ViewContext, + ) { + let range = range_utf16 + .as_ref() + .map(|range_utf16| self.range_from_utf16(range_utf16)) + .or(self.marked_range.clone()) + .unwrap_or(self.selected_range.clone()); + + self.text = + (self.text[0..range.start].to_owned() + new_text + &self.text[range.end..]).into(); + self.marked_range = Some(range.start..range.start + new_text.len()); + self.selected_range = new_selected_range_utf16 + .as_ref() + .map(|range_utf16| self.range_from_utf16(range_utf16)) + .map(|new_range| new_range.start + range.start..new_range.end + range.end) + .unwrap_or_else(|| range.start + new_text.len()..range.start + new_text.len()); + + cx.notify(); + } + + fn bounds_for_range( + &mut self, + range_utf16: Range, + bounds: Bounds, + _cx: &mut ViewContext, + ) -> Option> { + let last_layout = self.last_layout.as_ref()?; + let range = self.range_from_utf16(&range_utf16); + Some(Bounds::from_corners( + point( + bounds.left() + last_layout.x_for_index(range.start), + bounds.top(), + ), + point( + bounds.left() + last_layout.x_for_index(range.end), + bounds.bottom(), + ), + )) + } +} + +impl FocusableView for TextInput { + fn focus_handle(&self, _cx: &AppContext) -> FocusHandle { + self.focus_handle.clone() + } +} + +struct TextElement { + input: View, +} + +struct PrepaintState { + line: Option, + cursor: Option, + selection: Option, +} + +impl IntoElement for TextElement { + type Element = Self; + + fn into_element(self) -> Self::Element { + self + } +} + +impl Element for TextElement { + type RequestLayoutState = (); + + type PrepaintState = PrepaintState; + + fn id(&self) -> Option { + None + } + + fn request_layout( + &mut self, + _id: Option<&GlobalElementId>, + cx: &mut WindowContext, + ) -> (LayoutId, Self::RequestLayoutState) { + let mut style = Style::default(); + style.size.width = relative(1.).into(); + style.size.height = cx.line_height().into(); + (cx.request_layout(style, []), ()) + } + + fn prepaint( + &mut self, + _id: Option<&GlobalElementId>, + bounds: Bounds, + _request_layout: &mut Self::RequestLayoutState, + cx: &mut WindowContext, + ) -> Self::PrepaintState { + let input = self.input.read(cx); + let text = input.text.clone(); + let placeholder = input.placeholder.clone(); + let selected_range = input.selected_range.clone(); + let cursor = input.cursor_offset(); + let style = cx.text_style(); + + let (disaplay_text, text_color) = if text.is_empty() { + (placeholder, cx.theme().muted_foreground) + } else if input.masked { + ( + "*".repeat(text.chars().count()).into(), + cx.theme().foreground, + ) + } else { + (text, cx.theme().foreground) + }; + + let run = TextRun { + len: input.text.len(), + font: style.font(), + color: text_color, + background_color: None, + underline: None, + strikethrough: None, + }; + + let runs = if let Some(marked_range) = input.marked_range.as_ref() { + vec![ + TextRun { + len: marked_range.start, + ..run.clone() + }, + TextRun { + len: marked_range.end - marked_range.start, + underline: Some(UnderlineStyle { + color: Some(run.color), + thickness: px(1.0), + wavy: false, + }), + ..run.clone() + }, + TextRun { + len: disaplay_text.len() - marked_range.end, + ..run.clone() + }, + ] + .into_iter() + .filter(|run| run.len > 0) + .collect() + } else { + vec![run] + }; + + let font_size = style.font_size.to_pixels(cx.rem_size()); + let line = cx + .text_system() + .shape_line(disaplay_text, font_size, &runs) + .unwrap(); + + let cursor_pos = line.x_for_index(cursor); + let (selection, cursor) = if selected_range.is_empty() { + ( + None, + Some(fill( + Bounds::new( + point(bounds.left() + cursor_pos, bounds.top()), + size(px(1.5), bounds.bottom() - bounds.top()), + ), + gpui::blue(), + )), + ) + } else { + ( + Some(fill( + Bounds::from_corners( + point( + bounds.left() + line.x_for_index(selected_range.start), + bounds.top(), + ), + point( + bounds.left() + line.x_for_index(selected_range.end), + bounds.bottom(), + ), + ), + cx.theme().selection, + )), + None, + ) + }; + PrepaintState { + line: Some(line), + cursor, + selection, + } + } + + fn paint( + &mut self, + _id: Option<&GlobalElementId>, + bounds: Bounds, + _request_layout: &mut Self::RequestLayoutState, + prepaint: &mut Self::PrepaintState, + cx: &mut WindowContext, + ) { + let focus_handle = self.input.read(cx).focus_handle.clone(); + let is_focused = focus_handle.is_focused(cx); + + cx.handle_input( + &focus_handle, + ElementInputHandler::new(bounds, self.input.clone()), + ); + if let Some(selection) = prepaint.selection.take() { + cx.paint_quad(selection) + } + let line = prepaint.line.take().unwrap(); + line.paint(bounds.origin, cx.line_height(), cx).unwrap(); + + if is_focused { + if let Some(cursor) = prepaint.cursor.take() { + cx.paint_quad(cursor); + } + } + self.input.update(cx, |input, _cx| { + input.last_layout = Some(line); + }); + } +} + +impl Render for TextInput { + fn render(&mut self, cx: &mut ViewContext) -> impl IntoElement { + let focused = self.focus_handle.is_focused(cx); + div() + .flex() + .key_context("TextInput") + .track_focus(&self.focus_handle) + .when(!self.disabled, |this| { + this.on_action(cx.listener(Self::backspace)) + .on_action(cx.listener(Self::delete)) + }) + .on_action(cx.listener(Self::left)) + .on_action(cx.listener(Self::right)) + .on_action(cx.listener(Self::select_left)) + .on_action(cx.listener(Self::select_right)) + .on_action(cx.listener(Self::select_all)) + .on_action(cx.listener(Self::home)) + .on_action(cx.listener(Self::end)) + .on_action(cx.listener(Self::show_character_palette)) + .on_action(cx.listener(Self::copy)) + .on_action(cx.listener(Self::paste)) + .on_action(cx.listener(Self::cut)) + .on_action(cx.listener(Self::move_to_start_of_line)) + .on_action(cx.listener(Self::move_to_end_of_line)) + // Double click to select all + .on_double_click(cx.listener(|view, _, cx| { + view.select_all(&SelectAll, cx); + })) + .size_full() + .line_height(rems(1.25)) + .text_size(rems(0.875)) + .py_2() + .h_10() + .when(self.appearance, |this| { + this.bg(cx.theme().input) + .border_color(if focused { + cx.theme().ring + } else { + cx.theme().input + }) + .border_1() + .rounded_sm() + .shadow_sm() + .px_3() + .bg(if self.disabled { + cx.theme().muted + } else { + cx.theme().background + }) + }) + .child(div().w_full().child(TextElement { + input: cx.view().clone(), + })) + } +} diff --git a/crates/ui/src/lib.rs b/crates/ui/src/lib.rs index d861c5de..252b566f 100644 --- a/crates/ui/src/lib.rs +++ b/crates/ui/src/lib.rs @@ -1,5 +1,6 @@ mod clickable; mod disableable; +mod event; mod icon; mod platform; mod prelude; @@ -11,12 +12,12 @@ pub mod button; pub mod checkbox; pub mod empty; pub mod label; -pub mod text_field; pub mod theme; pub mod title_bar; pub use styled_ext::StyledExt; pub mod divider; // pub mod dropdown; +pub mod input; pub mod list; pub mod picker; pub mod switch; diff --git a/crates/ui/src/picker.rs b/crates/ui/src/picker.rs index 719f9202..df92a2a4 100644 --- a/crates/ui/src/picker.rs +++ b/crates/ui/src/picker.rs @@ -24,8 +24,8 @@ actions!( ); use crate::{ - divider::Divider, empty::Empty, label::Label, stock::*, text_field::TextField, - theme::ActiveTheme, StyledExt as _, + divider::Divider, empty::Empty, input::TextInput, label::Label, stock::*, theme::ActiveTheme, + StyledExt as _, }; enum ElementContainer { @@ -58,7 +58,7 @@ pub trait PickerDelegate: Sized + 'static { fn should_dismiss(&self) -> bool { true } - fn render_query(&self, input: &View, _cx: &mut ViewContext>) -> Div { + fn render_query(&self, input: &View, _cx: &mut ViewContext>) -> Div { v_flex() .child( h_flex() @@ -86,7 +86,7 @@ pub trait PickerDelegate: Sized + 'static { } fn finalize_update_matches( &mut self, - _query: String, + _query: SharedString, _duration: Duration, _cx: &mut ViewContext>, ) -> bool { @@ -117,7 +117,7 @@ struct PendingUpdateMatches { pub struct Picker { delegate: D, element_container: ElementContainer, - query_input: Option>, + query_input: Option>, width: Option, max_height: Option, is_modal: bool, @@ -130,7 +130,7 @@ impl Picker { fn new( delegate: D, kind: ContainerKind, - query_input: Option>, + query_input: Option>, cx: &mut ViewContext, ) -> Self { let element_container = match kind { @@ -172,9 +172,9 @@ impl Picker { fn new_query_input( placehoder: impl Into, cx: &mut ViewContext, - ) -> View { + ) -> View { cx.new_view(|cx| { - let mut input = TextField::new(cx).appearance(false); + let mut input = TextInput::new(cx).appearance(false); input.set_placeholder(placehoder, cx); input }) @@ -212,16 +212,16 @@ impl Picker { pub fn set_query(&mut self, query: &str, cx: &mut ViewContext) { if let Some(input) = &self.query_input { - input.update(cx, |this, cx| this.set_text(query, cx)); + input.update(cx, |this, cx| this.set_text(query.to_string(), cx)); } } /// Return the query input string. - pub fn query(&self, cx: &AppContext) -> String { + pub fn query(&self, cx: &AppContext) -> SharedString { if let Some(input) = &self.query_input { - input.read(cx).text(cx) + input.read(cx).text() } else { - String::new() + "".into() } } diff --git a/crates/ui/src/text_field/blink_manager.rs b/crates/ui/src/text_field/blink_manager.rs deleted file mode 100644 index 6a09c1ae..00000000 --- a/crates/ui/src/text_field/blink_manager.rs +++ /dev/null @@ -1,71 +0,0 @@ -use std::time::Duration; - -use gpui::{ModelContext, Timer}; - -pub struct BlinkManager { - blink_interval: Duration, - blink_epoch: usize, - blinking_paused: bool, - visible: bool, - enabled: bool, -} - -impl BlinkManager { - pub fn new(blink_interval: Duration, _cx: &mut ModelContext) -> Self { - Self { - blink_interval, - blink_epoch: 0, - blinking_paused: false, - visible: true, - enabled: true, - } - } - - pub fn pause_blinking(&mut self, cx: &mut ModelContext) { - self.show_cursor(cx); - - let epoch = self.next_blink_epoch(); - let interval = self.blink_interval; - cx.spawn(|this, mut cx| async move { - Timer::after(interval).await; - this.update(&mut cx, |this, cx| this.resume_cursor_blinking(epoch, cx)) - }) - .detach(); - } - - fn next_blink_epoch(&mut self) -> usize { - self.blink_epoch += 1; - self.blink_epoch - } - - fn resume_cursor_blinking(&mut self, epoch: usize, cx: &mut ModelContext) { - if epoch == self.blink_epoch { - self.blinking_paused = false; - self.blink_cursor(epoch, cx); - } - } - - pub fn show_cursor(&self, _cx: &mut ModelContext<'_, Self>) -> bool { - self.enabled && (!self.blinking_paused || self.visible) - } - - pub fn blink_cursor(&mut self, epoch: usize, cx: &mut ModelContext) { - if self.blink_epoch != epoch { - self.blink_epoch = epoch; - self.visible = !self.visible; - cx.refresh(); - } - } - - pub fn disable(&mut self, _cx: &mut ModelContext) { - self.enabled = false; - } - - pub fn enable(&mut self, _cx: &mut ModelContext) { - self.enabled = true; - } - - pub fn visible(&self) -> bool { - self.visible - } -} diff --git a/crates/ui/src/text_field/cursor_layout.rs b/crates/ui/src/text_field/cursor_layout.rs deleted file mode 100644 index 16bf6e89..00000000 --- a/crates/ui/src/text_field/cursor_layout.rs +++ /dev/null @@ -1,66 +0,0 @@ -use gpui::{ - fill, outline, px, size, Bounds, Hsla, Pixels, ShapedLine, Size, ViewContext, WindowContext, -}; - -#[derive(Debug, Clone)] -pub struct CursorLayout { - origin: gpui::Point, - #[allow(unused)] - block_width: Pixels, - line_height: Pixels, - color: Hsla, - block_text: Option, -} - -impl CursorLayout { - pub fn new( - origin: gpui::Point, - block_width: Pixels, - line_height: Pixels, - color: Hsla, - block_text: Option, - ) -> CursorLayout { - CursorLayout { - origin, - block_width, - line_height, - color, - block_text, - } - } - - fn bounds(&self, origin: gpui::Point) -> Bounds { - // Return a bar sharp cursor - Bounds { - origin: self.origin + origin, - size: size(px(2.0), self.line_height), - } - } - - pub fn layout(&mut self, origin: gpui::Point, cx: &mut WindowContext) { - let bounds = self.bounds(origin); - let cursor = fill(bounds, self.color); - - cx.paint_quad(cursor); - - if let Some(block_text) = &self.block_text { - block_text - .paint(self.origin + origin, self.line_height, cx) - .unwrap() - } - } - - pub fn paint(&mut self, origin: gpui::Point, cx: &mut WindowContext) { - let bounds = self.bounds(origin); - - let cursor = outline(bounds, self.color); - - cx.paint_quad(cursor); - - if let Some(block_text) = &self.block_text { - block_text - .paint(self.origin + origin, self.line_height, cx) - .unwrap() - } - } -} diff --git a/crates/ui/src/text_field/mod.rs b/crates/ui/src/text_field/mod.rs deleted file mode 100644 index 9db2b230..00000000 --- a/crates/ui/src/text_field/mod.rs +++ /dev/null @@ -1,269 +0,0 @@ -mod blink_manager; -mod cursor_layout; -mod text_view; - -use crate::{h_flex, theme::ActiveTheme}; -use gpui::{ - div, prelude::FluentBuilder as _, AppContext, ClipboardItem, Div, EventEmitter, FocusHandle, - FocusableView, InteractiveElement, Interactivity, IntoElement, KeyDownEvent, MouseButton, - ParentElement, Render, RenderOnce, SharedString, Style, StyleRefinement, Styled, View, - ViewContext, WindowContext, -}; -use std::{sync::Arc, time::Duration}; -use text_view::TextView; - -const CURSOR_BLINK_INTERVAL: Duration = Duration::from_millis(500); - -pub struct TextField { - focus_handle: FocusHandle, - appearance: bool, - pub view: View, -} - -impl TextField { - pub fn new(cx: &mut WindowContext) -> Self { - let focus_handle = cx.focus_handle(); - let view = TextView::init(cx, &focus_handle); - - Self { - focus_handle, - view, - appearance: true, - } - } - - pub fn focus(&mut self, cx: &mut WindowContext) { - cx.focus(&self.focus_handle); - } - - /// Set the appearance of the text field. - /// - /// If false, the text field will not have a border, background and focus ring. - pub fn appearance(mut self, appearance: bool) -> Self { - self.appearance = appearance; - self - } - - pub fn set_placeholder( - &mut self, - placeholder: impl Into, - cx: &mut WindowContext, - ) { - self.view.update(cx, |text_view, cx| { - text_view.set_placeholder(placeholder, cx) - }); - } - - pub fn set_disabled(&mut self, disabled: bool, cx: &mut WindowContext) { - self.view - .update(cx, |text_view, cx| text_view.set_disabled(disabled, cx)); - } - - pub fn set_text(&mut self, text: &str, cx: &mut WindowContext) { - self.view - .update(cx, |text_view, cx| text_view.set_text(text, cx)); - } - - pub fn text(&self, cx: &AppContext) -> String { - self.view.read(cx).text.clone() - } - - pub fn set_masked(&mut self, masked: bool, cx: &mut WindowContext) { - self.view - .update(cx, |text_view, cx| text_view.set_masked(masked, cx)); - } -} - -impl FocusableView for TextField { - fn focus_handle(&self, _cx: &gpui::AppContext) -> FocusHandle { - self.focus_handle.clone() - } -} - -impl Render for TextField { - fn render(&mut self, cx: &mut gpui::ViewContext) -> impl IntoElement { - let focus_handle = self.focus_handle.clone(); - let theme = cx.theme(); - - let view = self.view.clone(); - let text_view = view.read(cx); - - let focused = self.focus_handle.is_focused(cx); - let disabled = text_view.disabled; - - h_flex() - .w_full() - .track_focus(&focus_handle) - .when(!text_view.disabled, |this| { - this.on_mouse_down( - MouseButton::Left, - cx.listener(move |view, _, cx| { - cx.prevent_default(); - view.focus_handle.focus(cx) - }), - ) - }) - .when(!disabled, |this| { - this.on_key_down(cx.listener(move |this, ev: &KeyDownEvent, cx| { - this.view.update(cx, |text_view, cx| { - let prev = text_view.text.clone(); - cx.emit(TextEvent::KeyDown(ev.clone())); - let keystroke = ev.keystroke.key.as_str(); - let chars = text_view.text.chars().collect::>(); - let m = ev.keystroke.modifiers.secondary(); - - if m { - match keystroke { - "a" => { - text_view.selection = 0..chars.len(); - } - "c" => { - // if !text_view.masked { - let selected_text = - chars[text_view.selection.clone()].iter().collect(); - cx.write_to_clipboard(ClipboardItem::new(selected_text)); - // } - } - "v" => { - let clipboard = cx.read_from_clipboard(); - if let Some(clipboard) = clipboard { - let text = clipboard.text(); - text_view.text.replace_range( - text_view.char_range_to_text_range(&text_view.text), - text, - ); - let i = text_view.selection.start + text.chars().count(); - text_view.selection = i..i; - } - } - "x" => { - let selected_text = - chars[text_view.selection.clone()].iter().collect(); - cx.write_to_clipboard(ClipboardItem::new(selected_text)); - text_view.text.replace_range( - text_view.char_range_to_text_range(&text_view.text), - "", - ); - text_view.selection.end = text_view.selection.start; - } - _ => {} - } - } else if ev.keystroke.modifiers.control { - // On macOS, ctrl+a, ctrl+e are used for moving cursor to start/end of line - match keystroke { - "a" => { - // Move cursor to first of line - text_view.selection = 0..0; - } - "e" => { - // Move cursor to end of line - text_view.selection = chars.len()..chars.len(); - } - _ => {} - } - } else if !ev.keystroke.ime_key.clone().unwrap_or_default().is_empty() { - let ime_key = &ev.keystroke.ime_key.clone().unwrap_or_default(); - text_view.text.replace_range( - text_view.char_range_to_text_range(&text_view.text), - ime_key, - ); - let i = text_view.selection.start + ime_key.chars().count(); - text_view.selection = i..i; - } else { - match keystroke { - "left" => { - if text_view.selection.start > 0 { - let i = if text_view.selection.start - == text_view.selection.end - { - text_view.selection.start - 1 - } else { - text_view.selection.start - }; - text_view.selection = i..i; - } - } - "right" => { - if text_view.selection.end < text_view.text.len() { - let i = if text_view.selection.start - == text_view.selection.end - { - text_view.selection.end + 1 - } else { - text_view.selection.end - }; - text_view.selection = i..i; - } - } - "backspace" => { - if text_view.text.is_empty() && !ev.is_held { - // cx.emit(TextEvent::Back); - } else if text_view.selection.start == text_view.selection.end - && text_view.selection.start > 0 - { - let i = (text_view.selection.start - 1).min(chars.len()); - text_view.text = chars[0..i].iter().collect::() - + &(chars[text_view.selection.end.min(chars.len())..] - .iter() - .collect::()); - text_view.selection = i..i; - } else { - text_view.text.replace_range( - text_view.char_range_to_text_range(&text_view.text), - "", - ); - text_view.selection.end = text_view.selection.start; - } - } - "enter" => { - if ev.keystroke.modifiers.shift { - text_view.text.insert( - text_view - .char_range_to_text_range(&text_view.text) - .start, - '\n', - ); - let i = text_view.selection.start + 1; - text_view.selection = i..i; - } - } - _ => {} - }; - } - - if prev != text_view.text { - cx.emit(TextEvent::Input { - text: text_view.text.clone(), - }); - } - cx.notify(); - }); - })) - }) - .when(self.appearance, |this| { - this.border_color(if focused { theme.ring } else { theme.input }) - .border_1() - .rounded_sm() - .py_1() - .px_3() - .h_9() - .shadow_sm() - .bg(if disabled { - theme.muted - } else { - theme.background - }) - }) - .min_w_20() - .child(view) - } -} - -pub enum TextEvent { - Input { text: String }, - Blur, - Focus, - KeyDown(KeyDownEvent), -} - -impl EventEmitter for TextField {} diff --git a/crates/ui/src/text_field/text_view.rs b/crates/ui/src/text_field/text_view.rs deleted file mode 100644 index 305a2a24..00000000 --- a/crates/ui/src/text_field/text_view.rs +++ /dev/null @@ -1,376 +0,0 @@ -use std::ops::Range; - -use super::{ - blink_manager::BlinkManager, cursor_layout::CursorLayout, TextEvent, CURSOR_BLINK_INTERVAL, -}; -use crate::theme::{ActiveTheme, Colorize as _}; -use gpui::{ - px, relative, ContentMask, Context, Element, EventEmitter, FocusHandle, HighlightStyle, Hsla, - InteractiveText, IntoElement, Model, Point, Render, SharedString, Style, StyledText, TextStyle, - TextStyleRefinement, View, ViewContext, VisualContext, WindowContext, -}; - -#[derive(Clone)] -pub struct TextFieldStyle { - pub background: Hsla, - pub text: TextStyle, -} - -pub struct TextView { - pub text: String, - pub style: TextFieldStyle, - pub placeholder: SharedString, - pub word_click: (usize, u16), - pub selection: Range, - pub disabled: bool, - pub blink_manager: Model, - pub masked: bool, - pub focused: bool, -} - -impl EventEmitter for TextView {} - -impl TextView { - pub fn init(cx: &mut WindowContext, focus_handle: &FocusHandle) -> View { - let blink_manager = cx.new_model(|cx| BlinkManager::new(CURSOR_BLINK_INTERVAL, cx)); - - let theme = cx.theme(); - - let line_height = px(20.0); - let style = TextFieldStyle { - background: theme.transparent, - text: TextStyle { - color: theme.foreground, - line_height: line_height.into(), - ..Default::default() - }, - }; - - let m = Self { - text: String::new(), - style, - placeholder: "".into(), - word_click: (0, 0), - selection: 0..0, - blink_manager: blink_manager.clone(), - disabled: false, - masked: false, - focused: false, - }; - - let view = cx.new_view(|cx| { - cx.on_blur(focus_handle, |view: &mut TextView, cx| { - view.blur(cx); - }) - .detach(); - - cx.on_focus(focus_handle, |view, cx| { - view.focus(cx); - }) - .detach(); - - cx.observe(&blink_manager, |_, _, cx| cx.notify()).detach(); - - cx.observe_window_activation(|view, cx| { - let active = cx.is_window_active(); - view.blink_manager.update(cx, |blink_manager, cx| { - if active { - blink_manager.enable(cx); - } else { - blink_manager.show_cursor(cx); - blink_manager.disable(cx); - } - }) - }) - .detach(); - - m - }); - - cx.subscribe( - &view, - move |subscriber, emitter: &TextEvent, cx| match emitter { - TextEvent::Input { text: _ } => { - subscriber.update(cx, |editor, _cx| { - editor.word_click = (0, 0); - }); - } - TextEvent::Blur => { - subscriber.update(cx, |editor, cx| { - editor.blink_manager.update(cx, BlinkManager::disable); - editor.word_click = (0, 0); - }); - } - _ => {} - }, - ) - .detach(); - - view - } - - pub fn select_all(&mut self, cx: &mut ViewContext) { - self.selection = 0..self.text.len(); - cx.notify(); - } - - pub fn blur(&mut self, cx: &mut ViewContext) { - self.focused = false; - self.blink_manager.update(cx, BlinkManager::disable); - cx.notify(); - cx.emit(TextEvent::Blur); - } - - pub fn focus(&mut self, cx: &mut ViewContext) { - self.focused = true; - self.blink_manager.update(cx, |bm, cx| { - bm.blink_cursor(0, cx); - }); - cx.notify(); - cx.emit(TextEvent::Focus); - } - - pub fn word_ranges(&self) -> Vec> { - let mut words = Vec::new(); - let mut last_was_boundary = true; - let mut word_start = 0; - let s = self.text.clone(); - - for (i, c) in s.char_indices() { - if c.is_alphanumeric() || c == '_' { - if last_was_boundary { - word_start = i; - } - last_was_boundary = false; - } else { - if !last_was_boundary { - words.push(word_start..i); - } - last_was_boundary = true; - } - } - - // Check if the last characters form a word and push it if so - if !last_was_boundary { - words.push(word_start..s.len()); - } - - words - } - - /// Converts a character range to a text range (in bytes) - pub fn char_range_to_text_range(&self, text: &str) -> Range { - let start = text - .chars() - .take(self.selection.start) - .collect::() - .len(); - let end = text - .chars() - .take(self.selection.end) - .collect::() - .len(); - start..end - } - - pub fn set_text(&mut self, text: impl ToString, cx: &mut ViewContext) { - self.text = text.to_string(); - self.selection = self.text.len()..self.text.len(); - cx.notify(); - cx.emit(TextEvent::Input { - text: self.text.clone(), - }); - } - - pub fn set_masked(&mut self, masked: bool, cx: &mut ViewContext) { - self.masked = masked; - cx.notify(); - } - - pub fn set_placeholder( - &mut self, - placeholder: impl Into, - cx: &mut ViewContext, - ) { - self.placeholder = placeholder.into(); - cx.notify(); - } - - pub fn set_disabled(&mut self, disabled: bool, cx: &mut ViewContext) { - self.disabled = disabled; - cx.notify(); - } - - fn paint_cursors(&self, layout: &TextLayout, cx: &mut WindowContext) { - let mut cursor = layout.visible_cursor.clone(); - cursor.paint(layout.content_origin, cx); - } - - pub fn show_cursor(&self, cx: &mut WindowContext) -> bool { - self.blink_manager.read(cx).visible() && self.focused - } - - fn layout_visible_cursors(&self, cx: &mut WindowContext) -> CursorLayout { - let theme = cx.theme(); - let selection = &self.selection; - - let x = px(selection.end as f32); - let y = px(0.); - - CursorLayout::new(Point::new(x, y), px(0.), px(20.0), theme.ring, None) - } -} - -impl IntoElement for TextView { - type Element = Self; - - fn into_element(self) -> Self::Element { - self - } -} - -pub struct TextLayout { - content_origin: gpui::Point, - visible_cursor: CursorLayout, -} - -impl Element for TextView { - type RequestLayoutState = (); - - type PrepaintState = TextLayout; - - fn id(&self) -> Option { - None - } - - fn request_layout( - &mut self, - _id: Option<&gpui::GlobalElementId>, - cx: &mut WindowContext, - ) -> (gpui::LayoutId, Self::RequestLayoutState) { - let mut style = Style::default(); - let rem_size = cx.rem_size(); - - style.size.width = relative(1.).into(); - style.size.height = self.style.text.line_height_in_pixels(rem_size).into(); - - (cx.request_layout(style, None), ()) - } - - fn prepaint( - &mut self, - _id: Option<&gpui::GlobalElementId>, - bounds: gpui::Bounds, - _request_layout: &mut Self::RequestLayoutState, - cx: &mut WindowContext, - ) -> Self::PrepaintState { - let text_style = TextStyleRefinement { - font_size: Some(self.style.text.font_size), - line_height: Some(self.style.text.line_height), - ..Default::default() - }; - - cx.with_text_style(Some(text_style), |cx| { - cx.with_content_mask(Some(ContentMask { bounds }), |cx| { - let cursor = self.layout_visible_cursors(cx); - - TextLayout { - content_origin: bounds.origin, - visible_cursor: cursor, - } - }) - }) - } - - fn paint( - &mut self, - _id: Option<&gpui::GlobalElementId>, - bounds: gpui::Bounds, - _request_layout: &mut Self::RequestLayoutState, - layout: &mut Self::PrepaintState, - cx: &mut WindowContext, - ) { - let text_style = TextStyleRefinement { - font_size: Some(self.style.text.font_size), - line_height: Some(self.style.text.line_height), - ..Default::default() - }; - - cx.with_text_style(Some(text_style), |cx| { - cx.with_content_mask(Some(ContentMask { bounds }), |cx| { - self.paint_cursors(layout, cx); - }) - }); - } -} - -impl Render for TextView { - fn render(&mut self, cx: &mut ViewContext) -> impl IntoElement { - let theme = cx.theme(); - - let view = cx.view().clone(); - let mut text = self.text.clone(); - - let mut style = self.style.text.clone(); - if self.masked { - text = "•".repeat(text.len()); - } - - let selection_style = HighlightStyle { - background_color: Some(theme.ring), - color: Some(theme.ring.invert()), - ..Default::default() - }; - - let mut highlights = vec![(self.char_range_to_text_range(&text), selection_style)]; - - if text.is_empty() { - text = self.placeholder.to_string(); - style.color = theme.muted_foreground; - } else { - style.color = theme.foreground; - } - - if !self.focused { - highlights = vec![]; - } - - let styled_text = StyledText::new(text).with_highlights(&style, highlights); - - InteractiveText::new("text", styled_text).on_click( - self.word_ranges(), - move |range_ix, cx| { - view.update(cx, |text_view, cx| { - let (index, mut count) = text_view.word_click; - - if index == range_ix { - count += 1; - } else { - count = 1; - } - - match count { - 1 => { - // Position cursor at the beginning of the word - } - 2 => { - if text_view.masked { - text_view.selection = 0..text_view.text.len(); - } else { - let word_ranges = text_view.word_ranges(); - text_view.selection = word_ranges.get(range_ix).unwrap().clone(); - } - } - 3 | 4 => { - count = 0; - text_view.selection = 0..text_view.text.len(); - } - _ => {} - } - text_view.word_click = (range_ix, count); - cx.notify(); - }); - }, - ) - } -} diff --git a/crates/ui/src/theme.rs b/crates/ui/src/theme.rs index 0b16049b..416ab5c5 100644 --- a/crates/ui/src/theme.rs +++ b/crates/ui/src/theme.rs @@ -1,7 +1,4 @@ -use std::{cmp::min, sync::Arc}; - -use gpui::{AppContext, Global, Hsla, Rgba}; -use serde_json::json; +use gpui::{hsla, AppContext, Global, Hsla}; pub trait ActiveTheme { fn theme(&self) -> &Theme; @@ -13,13 +10,11 @@ impl ActiveTheme for AppContext { } } -fn hex(color: &str) -> Hsla { - let color: Rgba = serde_json::from_value(json!(color)).unwrap(); - color.into() -} - +/// h - 0 - 360.0 +/// s - 0.0 - 100.0 +/// l - 0.0 - 100.0 fn hsl(h: f32, s: f32, l: f32) -> Hsla { - Hsla { h, s, l, a: 1.0 } + hsla(h / 360., s / 100.0, l / 100.0, 1.0) } pub trait Colorize { @@ -74,53 +69,6 @@ impl Colorize for Hsla { } } -// @layer base { -// :root { -// --background: 0 0% 100%; -// --foreground: 240 10% 3.9%; -// --card: 0 0% 100%; -// --card-foreground: 240 10% 3.9%; -// --popover: 0 0% 100%; -// --popover-foreground: 240 10% 3.9%; -// --primary: 240 5.9% 10%; -// --primary-foreground: 0 0% 98%; -// --secondary: 240 4.8% 95.9%; -// --secondary-foreground: 240 5.9% 10%; -// --muted: 240 4.8% 95.9%; -// --muted-foreground: 240 3.8% 46.1%; -// --accent: 240 4.8% 95.9%; -// --accent-foreground: 240 5.9% 10%; -// --destructive: 0 84.2% 60.2%; -// --destructive-foreground: 0 0% 98%; -// --border: 240 5.9% 90%; -// --input: 240 5.9% 90%; -// --ring: 240 5.9% 10%; -// --radius: 0rem; -// } - -// .dark { -// --background: 240 10% 3.9%; -// --foreground: 0 0% 98%; -// --card: 240 10% 3.9%; -// --card-foreground: 0 0% 98%; -// --popover: 240 10% 3.9%; -// --popover-foreground: 0 0% 98%; -// --primary: 0 0% 98%; -// --primary-foreground: 240 5.9% 10%; -// --secondary: 240 3.7% 15.9%; -// --secondary-foreground: 0 0% 98%; -// --muted: 240 3.7% 15.9%; -// --muted-foreground: 240 5% 64.9%; -// --accent: 240 3.7% 15.9%; -// --accent-foreground: 0 0% 98%; -// --destructive: 0 62.8% 30.6%; -// --destructive-foreground: 0 0% 98%; -// --border: 240 3.7% 15.9%; -// --input: 240 3.7% 15.9%; -// --ring: 240 4.9% 83.9%; -// } -// } - #[derive(Debug, Clone, Copy)] struct Colors { pub title_bar_background: Hsla, @@ -144,59 +92,106 @@ struct Colors { pub border: Hsla, pub input: Hsla, pub ring: Hsla, - pub radius: f32, + pub selection: Hsla, } impl Colors { + // .light { + // --title_bar_background: 0 0% 100%; + // --background: 0 0% 100%; + // --foreground: 240 10% 3.9%; + // --card: 0 0% 100%; + // --card-foreground: 240 10% 3.9%; + // --popover: 0 0% 100%; + // --popover-foreground: 240 10% 3.9%; + // --primary: 240 5.9% 10%; + // --primary-foreground: 0 0% 98%; + // --secondary: 240 4.8% 95.9%; + // --secondary-foreground: 240 5.9% 10%; + // --muted: 240 4.8% 95.9%; + // --muted-foreground: 240 3.8% 46.1%; + // --accent: 240 4.8% 95.9%; + // --accent-foreground: 240 5.9% 10%; + // --destructive: 0 84.2% 60.2%; + // --destructive-foreground: 0 0% 98%; + // --border: 240 5.9% 90%; + // --input: 240 5.9% 90%; + // --ring: 240 5.9% 10%; + // --radius: 0rem; + // --selection: 211 97% 85%; + // } fn light() -> Colors { Colors { - title_bar_background: hsl(0.0, 0.0, 1.0), - background: hsl(0.0, 0.0, 1.0), - foreground: hsl(240.0, 0.1, 0.039), - card: hsl(0.0, 0.0, 1.0), - card_foreground: hsl(240.0, 0.1, 0.039), + title_bar_background: hsl(0.0, 0.0, 100.), + background: hsl(0.0, 0.0, 100.), + foreground: hsl(240.0, 10., 3.9), + card: hsl(0.0, 0.0, 100.0), + card_foreground: hsl(240.0, 10.0, 3.9), popover: hsl(0.0, 0.0, 1.0), - popover_foreground: hsl(240.0, 0.1, 0.039), - primary: hsl(240.0, 0.059, 0.1), - primary_foreground: hsl(0.0, 0.0, 0.98), - secondary: hsl(240.0, 0.048, 0.959), - secondary_foreground: hsl(240.0, 0.059, 0.1), - muted: hsl(240.0, 0.048, 0.959), - muted_foreground: hsl(240.0, 0.038, 0.461), - accent: hsl(240.0, 0.05, 0.96), - accent_foreground: hsl(240.0, 0.059, 0.1), - destructive: hsl(0.0, 0.842, 0.602), - destructive_foreground: hsl(0.0, 0.0, 0.98), - border: hsl(240.0, 0.059, 0.9), - input: hsl(240.0, 0.059, 0.9), - ring: hsl(240.0, 0.059, 0.1), - radius: 0.0, + popover_foreground: hsl(240.0, 10.0, 3.9), + primary: hsl(240.0, 5.9, 10.0), + primary_foreground: hsl(0.0, 0.0, 98.0), + secondary: hsl(240.0, 4.8, 95.9), + secondary_foreground: hsl(240.0, 59.0, 10.0), + muted: hsl(240.0, 4.8, 95.9), + muted_foreground: hsl(240.0, 3.8, 46.1), + accent: hsl(240.0, 5.0, 96.0), + accent_foreground: hsl(240.0, 5.9, 10.0), + destructive: hsl(0.0, 84.2, 60.2), + destructive_foreground: hsl(0.0, 0.0, 98.0), + border: hsl(240.0, 5.9, 90.0), + input: hsl(240.0, 5.9, 90.0), + ring: hsl(240.0, 5.9, 10.0), + selection: hsl(211.0, 97.0, 85.0), } } + // .dark { + // --title_bar_background: 0 0% 12%; + // --background: 240 10% 3.9%; + // --foreground: 0 0% 98%; + // --card: 240 10% 3.9%; + // --card-foreground: 0 0% 98%; + // --popover: 240 10% 3.9%; + // --popover-foreground: 0 0% 98%; + // --primary: 0 0% 98%; + // --primary-foreground: 240 5.9% 10%; + // --secondary: 240 3.7% 15.9%; + // --secondary-foreground: 0 0% 98%; + // --muted: 240 3.7% 15.9%; + // --muted-foreground: 240 5% 64.9%; + // --accent: 240 3.7% 15.9%; + // --accent-foreground: 0 0% 98%; + // --destructive: 0 62.8% 30.6%; + // --destructive-foreground: 0 0% 98%; + // --border: 240 3.7% 15.9%; + // --input: 240 3.7% 15.9%; + // --ring: 240 4.9% 83.9%; + // --selection: 211 97% 85%; + // } fn dark() -> Colors { Colors { - title_bar_background: hsl(0.0, 0.0, 0.12), - background: hsl(0.0, 0.0, 0.06), - foreground: hsl(0.0, 0.0, 0.98), - card: hsl(299.0, 0.02, 0.09), - card_foreground: hsl(0.0, 0.0, 0.98), - popover: hsl(240.0, 0.1, 0.039), - popover_foreground: hsl(0.0, 0.0, 0.98), - primary: hsl(0.0, 0.0, 0.98), - primary_foreground: hsl(240.0, 0.059, 0.1), - secondary: hsl(0.0, 0.0, 0.12), - secondary_foreground: hsl(0.0, 0.0, 0.98), - muted: hsl(240.0, 0.037, 0.159), - muted_foreground: hsl(240.0, 0.05, 0.649), - accent: hsl(240.0, 0.037, 0.159), - accent_foreground: hsl(0.0, 0.0, 0.98), - destructive: hsl(0.0, 0.628, 0.306), - destructive_foreground: hsl(0.0, 0.0, 0.98), - border: hsl(0.0, 0.0, 0.17), - input: hsl(240.0, 0.037, 0.159), - ring: hsl(240.0, 0.049, 0.839), - radius: 0.0, + title_bar_background: hsl(0., 0., 12.), + background: hsl(0.0, 0.0, 6.0), + foreground: hsl(0., 0., 98.), + card: hsl(299.0, 2., 9.), + card_foreground: hsl(0.0, 0.0, 98.0), + popover: hsl(240.0, 10.0, 3.9), + popover_foreground: hsl(0.0, 0.0, 98.0), + primary: hsl(0.0, 0.0, 98.0), + primary_foreground: hsl(240.0, 5.9, 10.0), + secondary: hsl(240.0, 3.7, 15.9), + secondary_foreground: hsl(0.0, 0.0, 98.0), + muted: hsl(240.0, 3.7, 15.9), + muted_foreground: hsl(240.0, 5.0, 64.9), + accent: hsl(240.0, 3.7, 15.9), + accent_foreground: hsl(0.0, 0.0, 98.0), + destructive: hsl(0.0, 62.8, 30.6), + destructive_foreground: hsl(0.0, 0.0, 98.0), + border: hsl(240.0, 3.7, 15.9), + input: hsl(240.0, 3.7, 15.9), + ring: hsl(240.0, 4.9, 83.9), + selection: hsl(211.0, 97.0, 85.0), } } } @@ -227,6 +222,7 @@ pub struct Theme { pub border: Hsla, pub input: Hsla, pub ring: Hsla, + pub selection: Hsla, pub radius: f32, } @@ -264,7 +260,8 @@ impl From for Theme { border: colors.border, input: colors.input, ring: colors.ring, - radius: colors.radius, + selection: colors.selection, + radius: 0.0, } } } diff --git a/crates/workspace/src/lib.rs b/crates/workspace/src/lib.rs index d8a9df4b..aed54c8f 100644 --- a/crates/workspace/src/lib.rs +++ b/crates/workspace/src/lib.rs @@ -3,12 +3,12 @@ use prelude::FluentBuilder as _; use std::sync::Arc; use ui::{ - button::{Button, ButtonSize}, + button::ButtonSize, + input, label::Label, switch::{LabelSide, Switch}, theme::{ActiveTheme, Theme}, title_bar::TitleBar, - Clickable as _, StyledExt as _, }; use ui_story::Stories; use util::ResultExt as _; @@ -42,6 +42,8 @@ impl Workspace { ) -> Task>> { let window_bounds = Bounds::centered(None, size(px(1200.0), px(900.0)), cx); + input::init(cx); + cx.spawn(|mut cx| async move { let options = WindowOptions { window_bounds: Some(WindowBounds::Windowed(window_bounds)),