Add simple context menu
This commit is contained in:
parent
a1b40e1d71
commit
858bad0f50
5 changed files with 205 additions and 89 deletions
76
Cargo.lock
generated
76
Cargo.lock
generated
|
|
@ -289,15 +289,15 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "async-executor"
|
name = "async-executor"
|
||||||
version = "1.6.0"
|
version = "1.7.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "4b0c4a4f319e45986f347ee47fef8bf5e81c9abc3f6f58dc2391439f30df65f0"
|
checksum = "fc5ea910c42e5ab19012bab31f53cb4d63d54c3a27730f9a833a88efcf4bb52d"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"async-lock 2.8.0",
|
"async-lock 3.1.1",
|
||||||
"async-task",
|
"async-task",
|
||||||
"concurrent-queue",
|
"concurrent-queue",
|
||||||
"fastrand 2.0.1",
|
"fastrand 2.0.1",
|
||||||
"futures-lite 1.13.0",
|
"futures-lite 2.0.1",
|
||||||
"slab",
|
"slab",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
@ -339,14 +339,14 @@ version = "2.2.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "41ed9d5715c2d329bf1b4da8d60455b99b187f27ba726df2883799af9af60997"
|
checksum = "41ed9d5715c2d329bf1b4da8d60455b99b187f27ba726df2883799af9af60997"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"async-lock 3.1.0",
|
"async-lock 3.1.1",
|
||||||
"cfg-if 1.0.0",
|
"cfg-if 1.0.0",
|
||||||
"concurrent-queue",
|
"concurrent-queue",
|
||||||
"futures-io",
|
"futures-io",
|
||||||
"futures-lite 2.0.1",
|
"futures-lite 2.0.1",
|
||||||
"parking",
|
"parking",
|
||||||
"polling 3.3.0",
|
"polling 3.3.0",
|
||||||
"rustix 0.38.24",
|
"rustix 0.38.25",
|
||||||
"slab",
|
"slab",
|
||||||
"tracing",
|
"tracing",
|
||||||
"waker-fn",
|
"waker-fn",
|
||||||
|
|
@ -364,9 +364,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "async-lock"
|
name = "async-lock"
|
||||||
version = "3.1.0"
|
version = "3.1.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "deb2ab2aa8a746e221ab826c73f48bc6ba41be6763f0855cb249eb6d154cf1d7"
|
checksum = "655b9c7fe787d3b25cc0f804a1a8401790f0c5bc395beb5a64dc77d8de079105"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"event-listener 3.1.0",
|
"event-listener 3.1.0",
|
||||||
"event-listener-strategy",
|
"event-listener-strategy",
|
||||||
|
|
@ -386,7 +386,7 @@ dependencies = [
|
||||||
"cfg-if 1.0.0",
|
"cfg-if 1.0.0",
|
||||||
"event-listener 3.1.0",
|
"event-listener 3.1.0",
|
||||||
"futures-lite 1.13.0",
|
"futures-lite 1.13.0",
|
||||||
"rustix 0.38.24",
|
"rustix 0.38.25",
|
||||||
"windows-sys 0.48.0",
|
"windows-sys 0.48.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
@ -413,7 +413,7 @@ dependencies = [
|
||||||
"cfg-if 1.0.0",
|
"cfg-if 1.0.0",
|
||||||
"futures-core",
|
"futures-core",
|
||||||
"futures-io",
|
"futures-io",
|
||||||
"rustix 0.38.24",
|
"rustix 0.38.25",
|
||||||
"signal-hook-registry",
|
"signal-hook-registry",
|
||||||
"slab",
|
"slab",
|
||||||
"windows-sys 0.48.0",
|
"windows-sys 0.48.0",
|
||||||
|
|
@ -459,7 +459,7 @@ name = "atomicwrites"
|
||||||
version = "0.4.2"
|
version = "0.4.2"
|
||||||
source = "git+https://github.com/jackpot51/rust-atomicwrites#043ab4859d53ffd3d55334685303d8df39c9f768"
|
source = "git+https://github.com/jackpot51/rust-atomicwrites#043ab4859d53ffd3d55334685303d8df39c9f768"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"rustix 0.38.24",
|
"rustix 0.38.25",
|
||||||
"tempfile",
|
"tempfile",
|
||||||
"windows-sys 0.48.0",
|
"windows-sys 0.48.0",
|
||||||
]
|
]
|
||||||
|
|
@ -604,7 +604,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "6a37913e8dc4ddcc604f0c6d3bf2887c995153af3611de9e23c352b44c1b9118"
|
checksum = "6a37913e8dc4ddcc604f0c6d3bf2887c995153af3611de9e23c352b44c1b9118"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"async-channel 2.1.0",
|
"async-channel 2.1.0",
|
||||||
"async-lock 3.1.0",
|
"async-lock 3.1.1",
|
||||||
"async-task",
|
"async-task",
|
||||||
"fastrand 2.0.1",
|
"fastrand 2.0.1",
|
||||||
"futures-io",
|
"futures-io",
|
||||||
|
|
@ -932,7 +932,7 @@ dependencies = [
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "cosmic-config"
|
name = "cosmic-config"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
source = "git+https://github.com/pop-os/libcosmic#1caae11e8f11a1e838e950b7e25050f6428be63d"
|
source = "git+https://github.com/pop-os/libcosmic#001fd744c5f80c9ce058eb0e22ae92f19d12c844"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"atomicwrites",
|
"atomicwrites",
|
||||||
"cosmic-config-derive",
|
"cosmic-config-derive",
|
||||||
|
|
@ -946,7 +946,7 @@ dependencies = [
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "cosmic-config-derive"
|
name = "cosmic-config-derive"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
source = "git+https://github.com/pop-os/libcosmic#1caae11e8f11a1e838e950b7e25050f6428be63d"
|
source = "git+https://github.com/pop-os/libcosmic#001fd744c5f80c9ce058eb0e22ae92f19d12c844"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"quote",
|
"quote",
|
||||||
"syn 1.0.109",
|
"syn 1.0.109",
|
||||||
|
|
@ -1019,7 +1019,7 @@ dependencies = [
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "cosmic-theme"
|
name = "cosmic-theme"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
source = "git+https://github.com/pop-os/libcosmic#1caae11e8f11a1e838e950b7e25050f6428be63d"
|
source = "git+https://github.com/pop-os/libcosmic#001fd744c5f80c9ce058eb0e22ae92f19d12c844"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"almost",
|
"almost",
|
||||||
"cosmic-config",
|
"cosmic-config",
|
||||||
|
|
@ -1938,7 +1938,11 @@ version = "2.0.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "d3831c2651acb5177cbd83943f3d9c8912c5ad03c76afcc0e9511ba568ec5ebb"
|
checksum = "d3831c2651acb5177cbd83943f3d9c8912c5ad03c76afcc0e9511ba568ec5ebb"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
|
"fastrand 2.0.1",
|
||||||
"futures-core",
|
"futures-core",
|
||||||
|
"futures-io",
|
||||||
|
"memchr",
|
||||||
|
"parking",
|
||||||
"pin-project-lite",
|
"pin-project-lite",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
@ -2385,7 +2389,7 @@ dependencies = [
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "iced"
|
name = "iced"
|
||||||
version = "0.10.0"
|
version = "0.10.0"
|
||||||
source = "git+https://github.com/pop-os/libcosmic#1caae11e8f11a1e838e950b7e25050f6428be63d"
|
source = "git+https://github.com/pop-os/libcosmic#001fd744c5f80c9ce058eb0e22ae92f19d12c844"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"iced_accessibility",
|
"iced_accessibility",
|
||||||
"iced_core",
|
"iced_core",
|
||||||
|
|
@ -2400,7 +2404,7 @@ dependencies = [
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "iced_accessibility"
|
name = "iced_accessibility"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
source = "git+https://github.com/pop-os/libcosmic#1caae11e8f11a1e838e950b7e25050f6428be63d"
|
source = "git+https://github.com/pop-os/libcosmic#001fd744c5f80c9ce058eb0e22ae92f19d12c844"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"accesskit",
|
"accesskit",
|
||||||
"accesskit_winit",
|
"accesskit_winit",
|
||||||
|
|
@ -2409,7 +2413,7 @@ dependencies = [
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "iced_core"
|
name = "iced_core"
|
||||||
version = "0.10.0"
|
version = "0.10.0"
|
||||||
source = "git+https://github.com/pop-os/libcosmic#1caae11e8f11a1e838e950b7e25050f6428be63d"
|
source = "git+https://github.com/pop-os/libcosmic#001fd744c5f80c9ce058eb0e22ae92f19d12c844"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bitflags 1.3.2",
|
"bitflags 1.3.2",
|
||||||
"instant",
|
"instant",
|
||||||
|
|
@ -2423,7 +2427,7 @@ dependencies = [
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "iced_futures"
|
name = "iced_futures"
|
||||||
version = "0.7.0"
|
version = "0.7.0"
|
||||||
source = "git+https://github.com/pop-os/libcosmic#1caae11e8f11a1e838e950b7e25050f6428be63d"
|
source = "git+https://github.com/pop-os/libcosmic#001fd744c5f80c9ce058eb0e22ae92f19d12c844"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"futures",
|
"futures",
|
||||||
"iced_core",
|
"iced_core",
|
||||||
|
|
@ -2435,7 +2439,7 @@ dependencies = [
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "iced_graphics"
|
name = "iced_graphics"
|
||||||
version = "0.9.0"
|
version = "0.9.0"
|
||||||
source = "git+https://github.com/pop-os/libcosmic#1caae11e8f11a1e838e950b7e25050f6428be63d"
|
source = "git+https://github.com/pop-os/libcosmic#001fd744c5f80c9ce058eb0e22ae92f19d12c844"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bitflags 1.3.2",
|
"bitflags 1.3.2",
|
||||||
"bytemuck",
|
"bytemuck",
|
||||||
|
|
@ -2453,7 +2457,7 @@ dependencies = [
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "iced_renderer"
|
name = "iced_renderer"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
source = "git+https://github.com/pop-os/libcosmic#1caae11e8f11a1e838e950b7e25050f6428be63d"
|
source = "git+https://github.com/pop-os/libcosmic#001fd744c5f80c9ce058eb0e22ae92f19d12c844"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"iced_graphics",
|
"iced_graphics",
|
||||||
"iced_tiny_skia",
|
"iced_tiny_skia",
|
||||||
|
|
@ -2466,7 +2470,7 @@ dependencies = [
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "iced_runtime"
|
name = "iced_runtime"
|
||||||
version = "0.1.1"
|
version = "0.1.1"
|
||||||
source = "git+https://github.com/pop-os/libcosmic#1caae11e8f11a1e838e950b7e25050f6428be63d"
|
source = "git+https://github.com/pop-os/libcosmic#001fd744c5f80c9ce058eb0e22ae92f19d12c844"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"iced_core",
|
"iced_core",
|
||||||
"iced_futures",
|
"iced_futures",
|
||||||
|
|
@ -2476,7 +2480,7 @@ dependencies = [
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "iced_style"
|
name = "iced_style"
|
||||||
version = "0.9.0"
|
version = "0.9.0"
|
||||||
source = "git+https://github.com/pop-os/libcosmic#1caae11e8f11a1e838e950b7e25050f6428be63d"
|
source = "git+https://github.com/pop-os/libcosmic#001fd744c5f80c9ce058eb0e22ae92f19d12c844"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"iced_core",
|
"iced_core",
|
||||||
"once_cell",
|
"once_cell",
|
||||||
|
|
@ -2486,7 +2490,7 @@ dependencies = [
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "iced_tiny_skia"
|
name = "iced_tiny_skia"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
source = "git+https://github.com/pop-os/libcosmic#1caae11e8f11a1e838e950b7e25050f6428be63d"
|
source = "git+https://github.com/pop-os/libcosmic#001fd744c5f80c9ce058eb0e22ae92f19d12c844"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bytemuck",
|
"bytemuck",
|
||||||
"cosmic-text 0.9.0",
|
"cosmic-text 0.9.0",
|
||||||
|
|
@ -2504,7 +2508,7 @@ dependencies = [
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "iced_wgpu"
|
name = "iced_wgpu"
|
||||||
version = "0.11.1"
|
version = "0.11.1"
|
||||||
source = "git+https://github.com/pop-os/libcosmic#1caae11e8f11a1e838e950b7e25050f6428be63d"
|
source = "git+https://github.com/pop-os/libcosmic#001fd744c5f80c9ce058eb0e22ae92f19d12c844"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bitflags 1.3.2",
|
"bitflags 1.3.2",
|
||||||
"bytemuck",
|
"bytemuck",
|
||||||
|
|
@ -2526,7 +2530,7 @@ dependencies = [
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "iced_widget"
|
name = "iced_widget"
|
||||||
version = "0.1.3"
|
version = "0.1.3"
|
||||||
source = "git+https://github.com/pop-os/libcosmic#1caae11e8f11a1e838e950b7e25050f6428be63d"
|
source = "git+https://github.com/pop-os/libcosmic#001fd744c5f80c9ce058eb0e22ae92f19d12c844"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"iced_renderer",
|
"iced_renderer",
|
||||||
"iced_runtime",
|
"iced_runtime",
|
||||||
|
|
@ -2540,7 +2544,7 @@ dependencies = [
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "iced_winit"
|
name = "iced_winit"
|
||||||
version = "0.10.0"
|
version = "0.10.0"
|
||||||
source = "git+https://github.com/pop-os/libcosmic#1caae11e8f11a1e838e950b7e25050f6428be63d"
|
source = "git+https://github.com/pop-os/libcosmic#001fd744c5f80c9ce058eb0e22ae92f19d12c844"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"iced_graphics",
|
"iced_graphics",
|
||||||
"iced_runtime",
|
"iced_runtime",
|
||||||
|
|
@ -2703,7 +2707,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "cb0889898416213fab133e1d33a0e5858a48177452750691bde3666d0fdbaf8b"
|
checksum = "cb0889898416213fab133e1d33a0e5858a48177452750691bde3666d0fdbaf8b"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"hermit-abi",
|
"hermit-abi",
|
||||||
"rustix 0.38.24",
|
"rustix 0.38.25",
|
||||||
"windows-sys 0.48.0",
|
"windows-sys 0.48.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
@ -2838,7 +2842,7 @@ checksum = "89d92a4743f9a61002fae18374ed11e7973f530cb3a3255fb354818118b2203c"
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "libcosmic"
|
name = "libcosmic"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
source = "git+https://github.com/pop-os/libcosmic#1caae11e8f11a1e838e950b7e25050f6428be63d"
|
source = "git+https://github.com/pop-os/libcosmic#001fd744c5f80c9ce058eb0e22ae92f19d12c844"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"apply",
|
"apply",
|
||||||
"cosmic-config",
|
"cosmic-config",
|
||||||
|
|
@ -3002,9 +3006,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "lyon_algorithms"
|
name = "lyon_algorithms"
|
||||||
version = "1.0.3"
|
version = "1.0.4"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "00a0349cd8f0270781bb93a824b63df6178e3b4a27794e7be3ce3763f5a44d6e"
|
checksum = "a3bca95f9a4955b3e4a821fbbcd5edfbd9be2a9a50bb5758173e5358bfb4c623"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"lyon_path",
|
"lyon_path",
|
||||||
"num-traits",
|
"num-traits",
|
||||||
|
|
@ -4074,7 +4078,7 @@ dependencies = [
|
||||||
"cfg-if 1.0.0",
|
"cfg-if 1.0.0",
|
||||||
"concurrent-queue",
|
"concurrent-queue",
|
||||||
"pin-project-lite",
|
"pin-project-lite",
|
||||||
"rustix 0.38.24",
|
"rustix 0.38.25",
|
||||||
"tracing",
|
"tracing",
|
||||||
"windows-sys 0.48.0",
|
"windows-sys 0.48.0",
|
||||||
]
|
]
|
||||||
|
|
@ -4508,9 +4512,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rustix"
|
name = "rustix"
|
||||||
version = "0.38.24"
|
version = "0.38.25"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "9ad981d6c340a49cdc40a1028d9c6084ec7e9fa33fcb839cab656a267071e234"
|
checksum = "dc99bc2d4f1fed22595588a013687477aedf3cdcfb26558c559edb67b4d9b22e"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bitflags 2.4.1",
|
"bitflags 2.4.1",
|
||||||
"errno",
|
"errno",
|
||||||
|
|
@ -4863,7 +4867,7 @@ dependencies = [
|
||||||
"objc",
|
"objc",
|
||||||
"raw-window-handle 0.5.2",
|
"raw-window-handle 0.5.2",
|
||||||
"redox_syscall 0.4.1",
|
"redox_syscall 0.4.1",
|
||||||
"rustix 0.38.24",
|
"rustix 0.38.25",
|
||||||
"tiny-xlib",
|
"tiny-xlib",
|
||||||
"wasm-bindgen",
|
"wasm-bindgen",
|
||||||
"wayland-backend",
|
"wayland-backend",
|
||||||
|
|
@ -5058,7 +5062,7 @@ dependencies = [
|
||||||
"cfg-if 1.0.0",
|
"cfg-if 1.0.0",
|
||||||
"fastrand 2.0.1",
|
"fastrand 2.0.1",
|
||||||
"redox_syscall 0.4.1",
|
"redox_syscall 0.4.1",
|
||||||
"rustix 0.38.24",
|
"rustix 0.38.25",
|
||||||
"windows-sys 0.48.0",
|
"windows-sys 0.48.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
|
||||||
54
src/main.rs
54
src/main.rs
|
|
@ -7,7 +7,7 @@ use cosmic::{
|
||||||
iced::{
|
iced::{
|
||||||
clipboard, event, keyboard, subscription,
|
clipboard, event, keyboard, subscription,
|
||||||
widget::{row, text},
|
widget::{row, text},
|
||||||
window, Alignment, Length,
|
window, Alignment, Length, Point,
|
||||||
},
|
},
|
||||||
style,
|
style,
|
||||||
widget::{self, button, icon, nav_bar, segmented_button, view_switcher},
|
widget::{self, button, icon, nav_bar, segmented_button, view_switcher},
|
||||||
|
|
@ -21,7 +21,7 @@ use std::{
|
||||||
sync::Mutex,
|
sync::Mutex,
|
||||||
};
|
};
|
||||||
|
|
||||||
use config::{AppTheme, Config, CONFIG_VERSION};
|
use config::{Action, AppTheme, Config, CONFIG_VERSION};
|
||||||
mod config;
|
mod config;
|
||||||
|
|
||||||
mod localize;
|
mod localize;
|
||||||
|
|
@ -105,7 +105,7 @@ pub struct Flags {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
#[derive(Clone, Debug, Eq, PartialEq)]
|
#[derive(Clone, Debug, PartialEq)]
|
||||||
pub enum Message {
|
pub enum Message {
|
||||||
AppTheme(AppTheme),
|
AppTheme(AppTheme),
|
||||||
Config(Config),
|
Config(Config),
|
||||||
|
|
@ -133,6 +133,8 @@ pub enum Message {
|
||||||
TabActivate(segmented_button::Entity),
|
TabActivate(segmented_button::Entity),
|
||||||
TabChanged(segmented_button::Entity),
|
TabChanged(segmented_button::Entity),
|
||||||
TabClose(segmented_button::Entity),
|
TabClose(segmented_button::Entity),
|
||||||
|
TabContextAction(segmented_button::Entity, Action),
|
||||||
|
TabContextMenu(segmented_button::Entity, Option<Point>),
|
||||||
TabWidth(u16),
|
TabWidth(u16),
|
||||||
Todo,
|
Todo,
|
||||||
ToggleAutoIndent,
|
ToggleAutoIndent,
|
||||||
|
|
@ -829,6 +831,30 @@ impl Application for App {
|
||||||
|
|
||||||
return self.update_tab();
|
return self.update_tab();
|
||||||
}
|
}
|
||||||
|
Message::TabContextAction(entity, action) => {
|
||||||
|
match self.tab_model.data_mut::<Tab>(entity) {
|
||||||
|
Some(tab) => {
|
||||||
|
// Close context menu
|
||||||
|
tab.context_menu = None;
|
||||||
|
// Hack to ensure editor redraws
|
||||||
|
tab.editor.lock().unwrap().buffer_mut().set_redraw(true);
|
||||||
|
// Run action's message
|
||||||
|
return self.update(action.message());
|
||||||
|
}
|
||||||
|
None => {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Message::TabContextMenu(entity, position_opt) => {
|
||||||
|
match self.tab_model.data_mut::<Tab>(entity) {
|
||||||
|
Some(tab) => {
|
||||||
|
// Update context menu
|
||||||
|
tab.context_menu = position_opt;
|
||||||
|
// Hack to ensure editor redraws
|
||||||
|
tab.editor.lock().unwrap().buffer_mut().set_redraw(true);
|
||||||
|
}
|
||||||
|
None => {}
|
||||||
|
}
|
||||||
|
}
|
||||||
Message::TabWidth(tab_width) => {
|
Message::TabWidth(tab_width) => {
|
||||||
self.config.tab_width = tab_width;
|
self.config.tab_width = tab_width;
|
||||||
return self.save_config();
|
return self.save_config();
|
||||||
|
|
@ -1024,7 +1050,8 @@ impl Application for App {
|
||||||
.align_items(Alignment::Center),
|
.align_items(Alignment::Center),
|
||||||
);
|
);
|
||||||
|
|
||||||
match self.active_tab() {
|
let tab_id = self.tab_model.active();
|
||||||
|
match self.tab_model.data::<Tab>(tab_id) {
|
||||||
Some(tab) => {
|
Some(tab) => {
|
||||||
let status = {
|
let status = {
|
||||||
let editor = tab.editor.lock().unwrap();
|
let editor = tab.editor.lock().unwrap();
|
||||||
|
|
@ -1060,10 +1087,21 @@ impl Application for App {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
tab_column = tab_column.push(
|
let text_box = text_box(&tab.editor, self.config.metrics())
|
||||||
text_box(&tab.editor, self.config.metrics())
|
.on_changed(Message::TabChanged(tab_id))
|
||||||
.on_changed(Message::TabChanged(self.tab_model.active())),
|
.on_context_menu(move |position_opt| {
|
||||||
);
|
Message::TabContextMenu(tab_id, position_opt)
|
||||||
|
});
|
||||||
|
let tab_element: Element<'_, Message> = match tab.context_menu {
|
||||||
|
Some(position) => widget::popover(
|
||||||
|
text_box.context_menu(position),
|
||||||
|
menu::context_menu(&self.config, tab_id),
|
||||||
|
)
|
||||||
|
.position(position)
|
||||||
|
.into(),
|
||||||
|
None => text_box.into(),
|
||||||
|
};
|
||||||
|
tab_column = tab_column.push(tab_element);
|
||||||
tab_column = tab_column.push(text(status).font(cosmic::font::Font::MONOSPACE));
|
tab_column = tab_column.push(text(status).font(cosmic::font::Font::MONOSPACE));
|
||||||
}
|
}
|
||||||
None => {
|
None => {
|
||||||
|
|
|
||||||
71
src/menu.rs
71
src/menu.rs
|
|
@ -1,17 +1,69 @@
|
||||||
// SPDX-License-Identifier: GPL-3.0-only
|
// SPDX-License-Identifier: GPL-3.0-only
|
||||||
|
|
||||||
use cosmic::{
|
use cosmic::{
|
||||||
|
cosmic_theme,
|
||||||
//TODO: export in cosmic::widget
|
//TODO: export in cosmic::widget
|
||||||
iced::{widget::horizontal_rule, Alignment, Length},
|
iced::{
|
||||||
|
widget::{column, horizontal_rule},
|
||||||
|
Alignment, Length,
|
||||||
|
},
|
||||||
theme,
|
theme,
|
||||||
widget::{
|
widget::{
|
||||||
self, horizontal_space,
|
self, horizontal_space,
|
||||||
menu::{ItemHeight, ItemWidth, MenuBar, MenuTree},
|
menu::{ItemHeight, ItemWidth, MenuBar, MenuTree},
|
||||||
|
segmented_button,
|
||||||
},
|
},
|
||||||
Element,
|
Element,
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::{fl, Config, ContextPage, Message};
|
use crate::{fl, Action, Config, ContextPage, Message};
|
||||||
|
|
||||||
|
macro_rules! menu_button {
|
||||||
|
($($x:expr),+ $(,)?) => (
|
||||||
|
widget::button(
|
||||||
|
widget::Row::with_children(
|
||||||
|
vec![$(Element::from($x)),+]
|
||||||
|
)
|
||||||
|
.align_items(Alignment::Center)
|
||||||
|
)
|
||||||
|
.height(Length::Fixed(32.0))
|
||||||
|
.padding([4, 16])
|
||||||
|
.width(Length::Fill)
|
||||||
|
.style(theme::Button::MenuItem)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn context_menu<'a>(config: &Config, entity: segmented_button::Entity) -> Element<'a, Message> {
|
||||||
|
let menu_item = |label, action| {
|
||||||
|
let mut key = String::new();
|
||||||
|
for (key_bind, action) in config.keybinds.iter() {
|
||||||
|
if action == action {
|
||||||
|
key = key_bind.to_string();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
menu_button!(
|
||||||
|
widget::text(label),
|
||||||
|
horizontal_space(Length::Fill),
|
||||||
|
widget::text(key)
|
||||||
|
)
|
||||||
|
.on_press(Message::TabContextAction(entity, action))
|
||||||
|
};
|
||||||
|
|
||||||
|
widget::cosmic_container::container(column!(
|
||||||
|
menu_item(fl!("undo"), Action::Undo),
|
||||||
|
menu_item(fl!("redo"), Action::Redo),
|
||||||
|
horizontal_rule(1),
|
||||||
|
menu_item(fl!("cut"), Action::Cut),
|
||||||
|
menu_item(fl!("copy"), Action::Copy),
|
||||||
|
menu_item(fl!("paste"), Action::Paste),
|
||||||
|
menu_item(fl!("select-all"), Action::SelectAll),
|
||||||
|
))
|
||||||
|
.layer(cosmic_theme::Layer::Background)
|
||||||
|
.style(theme::Container::Card)
|
||||||
|
.width(Length::Fixed(240.0))
|
||||||
|
.into()
|
||||||
|
}
|
||||||
|
|
||||||
pub fn menu_bar<'a>(config: &Config) -> Element<'a, Message> {
|
pub fn menu_bar<'a>(config: &Config) -> Element<'a, Message> {
|
||||||
//TODO: port to libcosmic
|
//TODO: port to libcosmic
|
||||||
|
|
@ -21,21 +73,6 @@ pub fn menu_bar<'a>(config: &Config) -> Element<'a, Message> {
|
||||||
.style(theme::Button::MenuRoot)
|
.style(theme::Button::MenuRoot)
|
||||||
};
|
};
|
||||||
|
|
||||||
macro_rules! menu_button {
|
|
||||||
($($x:expr),+ $(,)?) => (
|
|
||||||
widget::button(
|
|
||||||
widget::Row::with_children(
|
|
||||||
vec![$(Element::from($x)),+]
|
|
||||||
)
|
|
||||||
.align_items(Alignment::Center)
|
|
||||||
)
|
|
||||||
.height(Length::Fixed(32.0))
|
|
||||||
.padding([4, 16])
|
|
||||||
.width(Length::Fill)
|
|
||||||
.style(theme::Button::MenuItem)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
let menu_folder =
|
let menu_folder =
|
||||||
|label| menu_button!(widget::text(label), horizontal_space(Length::Fill), ">");
|
|label| menu_button!(widget::text(label), horizontal_space(Length::Fill), ">");
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,9 @@
|
||||||
// SPDX-License-Identifier: GPL-3.0-only
|
// SPDX-License-Identifier: GPL-3.0-only
|
||||||
|
|
||||||
use cosmic::widget::{icon, Icon};
|
use cosmic::{
|
||||||
|
iced::Point,
|
||||||
|
widget::{icon, Icon},
|
||||||
|
};
|
||||||
use cosmic_text::{Attrs, Buffer, Edit, Shaping, SyntaxEditor, ViEditor, Wrap};
|
use cosmic_text::{Attrs, Buffer, Edit, Shaping, SyntaxEditor, ViEditor, Wrap};
|
||||||
use std::{fs, path::PathBuf, sync::Mutex};
|
use std::{fs, path::PathBuf, sync::Mutex};
|
||||||
|
|
||||||
|
|
@ -10,6 +13,7 @@ pub struct Tab {
|
||||||
pub path_opt: Option<PathBuf>,
|
pub path_opt: Option<PathBuf>,
|
||||||
attrs: Attrs<'static>,
|
attrs: Attrs<'static>,
|
||||||
pub editor: Mutex<ViEditor<'static>>,
|
pub editor: Mutex<ViEditor<'static>>,
|
||||||
|
pub context_menu: Option<Point>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Tab {
|
impl Tab {
|
||||||
|
|
@ -31,6 +35,7 @@ impl Tab {
|
||||||
path_opt: None,
|
path_opt: None,
|
||||||
attrs,
|
attrs,
|
||||||
editor: Mutex::new(ViEditor::new(editor)),
|
editor: Mutex::new(ViEditor::new(editor)),
|
||||||
|
context_menu: None,
|
||||||
};
|
};
|
||||||
|
|
||||||
// Update any other config settings
|
// Update any other config settings
|
||||||
|
|
|
||||||
|
|
@ -62,6 +62,8 @@ pub struct TextBox<'a, Message> {
|
||||||
metrics: Metrics,
|
metrics: Metrics,
|
||||||
padding: Padding,
|
padding: Padding,
|
||||||
on_changed: Option<Message>,
|
on_changed: Option<Message>,
|
||||||
|
context_menu: Option<Point>,
|
||||||
|
on_context_menu: Option<Box<dyn Fn(Option<Point>) -> Message + 'a>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, Message> TextBox<'a, Message>
|
impl<'a, Message> TextBox<'a, Message>
|
||||||
|
|
@ -74,6 +76,8 @@ where
|
||||||
metrics,
|
metrics,
|
||||||
padding: Padding::new(0.0),
|
padding: Padding::new(0.0),
|
||||||
on_changed: None,
|
on_changed: None,
|
||||||
|
context_menu: None,
|
||||||
|
on_context_menu: None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -86,6 +90,19 @@ where
|
||||||
self.on_changed = Some(on_changed);
|
self.on_changed = Some(on_changed);
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn context_menu(mut self, position: Point) -> Self {
|
||||||
|
self.context_menu = Some(position);
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn on_context_menu(
|
||||||
|
mut self,
|
||||||
|
on_context_menu: impl Fn(Option<Point>) -> Message + 'a,
|
||||||
|
) -> Self {
|
||||||
|
self.on_context_menu = Some(Box::new(on_context_menu));
|
||||||
|
self
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn text_box<'a, Message>(
|
pub fn text_box<'a, Message>(
|
||||||
|
|
@ -498,35 +515,50 @@ where
|
||||||
status = Status::Captured;
|
status = Status::Captured;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Event::Mouse(MouseEvent::ButtonPressed(Button::Left)) => {
|
Event::Mouse(MouseEvent::ButtonPressed(button)) => {
|
||||||
if let Some(p) = cursor_position.position_in(layout.bounds()) {
|
if let Some(p) = cursor_position.position_in(layout.bounds()) {
|
||||||
let x_logical = p.x - self.padding.left;
|
// Handle left click drag
|
||||||
let y_logical = p.y - self.padding.top;
|
if let Button::Left = button {
|
||||||
let x = x_logical * scale_factor;
|
let x_logical = p.x - self.padding.left;
|
||||||
let y = y_logical * scale_factor;
|
let y_logical = p.y - self.padding.top;
|
||||||
if x >= 0.0 && x < buffer_size.0 && y >= 0.0 && y < buffer_size.1 {
|
let x = x_logical * scale_factor;
|
||||||
editor.action(Action::Click {
|
let y = y_logical * scale_factor;
|
||||||
x: x as i32,
|
if x >= 0.0 && x < buffer_size.0 && y >= 0.0 && y < buffer_size.1 {
|
||||||
y: y as i32,
|
editor.action(Action::Click {
|
||||||
});
|
x: x as i32,
|
||||||
state.dragging = Some(Dragging::Buffer);
|
y: y as i32,
|
||||||
} else if scrollbar_rect.contains(Point::new(x_logical, y_logical)) {
|
});
|
||||||
state.dragging = Some(Dragging::Scrollbar {
|
state.dragging = Some(Dragging::Buffer);
|
||||||
start_y: y,
|
} else if scrollbar_rect.contains(Point::new(x_logical, y_logical)) {
|
||||||
start_scroll: editor.buffer().scroll(),
|
state.dragging = Some(Dragging::Scrollbar {
|
||||||
});
|
start_y: y,
|
||||||
} else if x_logical >= scrollbar_rect.x
|
start_scroll: editor.buffer().scroll(),
|
||||||
&& x_logical < (scrollbar_rect.x + scrollbar_rect.width)
|
});
|
||||||
{
|
} else if x_logical >= scrollbar_rect.x
|
||||||
let mut buffer = editor.buffer_mut();
|
&& x_logical < (scrollbar_rect.x + scrollbar_rect.width)
|
||||||
let scroll_offset =
|
{
|
||||||
((y / buffer.size().1) * buffer.lines.len() as f32) as i32;
|
let mut buffer = editor.buffer_mut();
|
||||||
buffer.set_scroll(scroll_offset);
|
let scroll_offset =
|
||||||
state.dragging = Some(Dragging::Scrollbar {
|
((y / buffer.size().1) * buffer.lines.len() as f32) as i32;
|
||||||
start_y: y,
|
buffer.set_scroll(scroll_offset);
|
||||||
start_scroll: editor.buffer().scroll(),
|
state.dragging = Some(Dragging::Scrollbar {
|
||||||
});
|
start_y: y,
|
||||||
|
start_scroll: editor.buffer().scroll(),
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Update context menu state
|
||||||
|
if let Some(on_context_menu) = &self.on_context_menu {
|
||||||
|
shell.publish((on_context_menu)(match self.context_menu {
|
||||||
|
Some(_) => None,
|
||||||
|
None => match button {
|
||||||
|
Button::Right => Some(p),
|
||||||
|
_ => None,
|
||||||
|
},
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
status = Status::Captured;
|
status = Status::Captured;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue