use std::collections::BTreeMap;
use super::Config;
use crate::app::overlay_for;
use crate::binding::{Action, Binding, ButtonId};
impl Config {
#[must_use]
pub fn effective_bindings(
&self,
device_key: &str,
bundle_id: Option<&str>,
) -> BTreeMap<ButtonId, Binding> {
let Some(device) = self.devices.get(device_key) else {
return BTreeMap::new();
};
let mut out = device.bindings.clone();
if let Some(bid) = bundle_id
&& let Some(overlay) = overlay_for(&device.per_app_bindings, bid)
{
for (k, v) in overlay {
out.insert(*k, Binding::Single(v.clone()));
}
}
out
}
pub fn set_per_app_binding(
&mut self,
device_key: &str,
bundle_id: &str,
button: ButtonId,
action: Option<Action>,
) {
let entry = self
.devices
.entry(device_key.to_string())
.or_default()
.per_app_bindings
.entry(bundle_id.to_string())
.or_default();
match action {
Some(a) => {
entry.insert(button, a);
}
None => {
entry.remove(&button);
}
}
if let Some(d) = self.devices.get_mut(device_key) {
d.per_app_bindings.retain(|_, m| !m.is_empty());
}
}
#[must_use]
pub fn per_app_overrides(
&self,
device_key: &str,
app: &str,
) -> Option<&BTreeMap<ButtonId, Action>> {
self.devices
.get(device_key)?
.per_app_bindings
.get(app)
.filter(|overrides| !overrides.is_empty())
}
pub fn app_profiles(&self, device_key: &str) -> impl Iterator<Item = &str> {
self.devices
.get(device_key)
.into_iter()
.flat_map(|device| device.per_app_bindings.keys().map(String::as_str))
}
pub fn remove_app_profile(&mut self, device_key: &str, app: &str) {
if let Some(device) = self.devices.get_mut(device_key) {
device.per_app_bindings.remove(app);
}
}
#[must_use]
pub fn has_app_override(&self, device_key: &str, app: &str) -> bool {
self.devices.get(device_key).is_some_and(|d| {
overlay_for(&d.per_app_bindings, app).is_some_and(|overlay| !overlay.is_empty())
})
}
}