use crate::icon::IconInfo;
use crate::utils::map_array;
use crate::{bindings::*, notify::NotifyLock};
use windows::core::{ComObject, HSTRING, implement};
use windows_core::Error;
#[implement(ISeparatorFilterItem, IFilterItem)]
pub struct SeparatorFilterItem;
impl ISeparatorFilterItem_Impl for SeparatorFilterItem_Impl {}
impl IFilterItem_Impl for SeparatorFilterItem_Impl {}
#[implement(IFilter, IFilterItem)]
pub struct FilterItem {
icon: Option<ComObject<IconInfo>>,
id: HSTRING,
name: HSTRING,
}
impl IFilter_Impl for FilterItem_Impl {
fn Icon(&self) -> windows_core::Result<IIconInfo> {
self.icon
.as_ref()
.map(|icon| icon.to_interface())
.ok_or(windows_core::Error::empty())
}
fn Id(&self) -> windows_core::Result<windows_core::HSTRING> {
Ok(self.id.clone())
}
fn Name(&self) -> windows_core::Result<windows_core::HSTRING> {
Ok(self.name.clone())
}
}
impl IFilterItem_Impl for FilterItem_Impl {}
pub enum Filter {
Separator(ComObject<SeparatorFilterItem>),
Item(ComObject<FilterItem>),
}
impl From<&Filter> for IFilterItem {
fn from(item: &Filter) -> Self {
match item {
Filter::Separator(item) => item.to_interface(),
Filter::Item(item) => item.to_interface(),
}
}
}
#[implement(IFilters)]
pub struct Filters {
filters: Vec<Filter>,
index: NotifyLock<usize>,
}
impl IFilters_Impl for Filters_Impl {
fn CurrentFilterId(&self) -> windows_core::Result<windows_core::HSTRING> {
let filter = self
.filters
.get(*self.index.read()?)
.ok_or(Error::empty())?;
match filter {
Filter::Separator(_) => Err(Error::empty()),
Filter::Item(item) => item.Id(),
}
}
fn Filters(&self) -> windows_core::Result<windows_core::Array<IFilterItem>> {
Ok(map_array(&self.filters, |filter| {
Some(IFilterItem::from(filter))
}))
}
fn SetCurrentFilterId(&self, value: &windows_core::HSTRING) -> windows_core::Result<()> {
for (i, filter) in self.filters.iter().enumerate() {
match filter {
Filter::Separator(_) => continue,
Filter::Item(item) => {
if item.Id()? == *value {
*self.index.write(|| {})? = i;
return Ok(());
}
}
}
}
Ok(())
}
}