我正在开发一个 dioxus 桌面应用程序,其中有一长串复选框。我希望能够通过 Shift 选择来立即检查其中的一系列内容,但不知道如何确定是否按下了 Shift 键。
我根据这个问题发现,如果我专注于复选框,我可以获得
onkeydown
事件,但我只能通过使用选项卡来聚焦复选框,所以这并不是我真正想要的。我尝试使用其他一些板条箱web-sys
,wasm-bindgen
,global-hotkey
,但没有任何运气。
我只需使用静态布尔值就可以实现逻辑工作
shift_pressed
,因此如果有人可以帮助我从 Shift 键的状态获取该布尔值,我将不胜感激。
#[component]
fn ChangeList(changes: Signal<Vec<ChangeItemInfo>>) -> Element {
let mut last_clicked = use_signal(|| 0);
let shift_pressed = true; // TODO: get this bool from the shift key
let mut group_select = move |just_clicked: usize, check: bool| {
// get the selection range indices
let first = std::cmp::min(just_clicked, *last_clicked.read());
let last = std::cmp::max(just_clicked, *last_clicked.read());
println!("Group Selecting from {first} to {last}");
// check or uncheck all the checkboxes in the range
changes.write().iter_mut().skip(first).take(last - first + 1).for_each(|c| c.checked = check);
};
rsx! {
div {class: "change-list",
header { // Display the number of changes
if changes.read().len() == 0 {
p {"No changes found"}
} else {
// make a check box that checks off all changes when checked
label { class: "checkbox_container",
input { r#type: "checkbox", checked:"false",
onchange: move |evt: FormEvent| {
let checked = evt.value() == "true";
changes.write().iter_mut().for_each(|c| c.checked = checked);
},
}
span { class: "checkmark" }
}
p {"{changes.read().len()} Changed Files"}
}
}
ul { // Display a check box, title, and symbol for each change
for (index, change) in changes.read().iter().enumerate() {
li { title: "{&change.change}", key: "{&change:?}",
label { class: "checkbox_container",
input { r#type: "checkbox", checked:"{change.checked}",
onchange: move |evt: FormEvent| {
let checked = evt.value() == "true";
if shift_pressed {
group_select(index, checked);
} else if let Some(c) = changes.write().get_mut(index) {
c.checked = checked; // check off the clicked check box
}
last_clicked.set(index);
},
}
span { class: "checkmark" }
}
p {"{change.change.path.file_name().unwrap().to_string_lossy()}"}
div { display:"flex", gap:"0.5rem", margin_left:"auto",
if change.conflict { img { src: mg!(file("assets/code_pull_request.svg")) } }
if change.change.r#type == ChangeType::New { img { src: mg!(file("assets/new.svg")) } }
if change.change.r#type == ChangeType::Modified { img { src: mg!(file("assets/modified.svg")) } }
if change.change.r#type == ChangeType::Deleted { img { src: mg!(file("assets/deleted.svg")) } }
}
}
}
}
}
}
}
我通过遵循这个示例弄清楚了如何拦截来自
wry
的事件。这就是我为找到此内容的人最终得到的结果:
use dioxus::prelude::*;
use dioxus::desktop::tao::event::Event as WryEvent;
use dioxus::desktop::tao::event::WindowEvent;
use dioxus::desktop::use_wry_event_handler;
let mut shift_pressed = use_signal(|| false);
use_wry_event_handler(move |event, _| {
if let WryEvent::WindowEvent {
event: WindowEvent::ModifiersChanged(state),
..
} = event
{
match state.bits() {
4 => shift_pressed.set(true),
0 => shift_pressed.set(false),
_ => {}
}
}
});