cmdpal 0.1.0

Rust SDK for PowerToys Command Palette
Documentation
use crate::cmd_item::CommandItem;
use crate::{bindings::*, notify::*};
use windows::core::{
    ComObject, ComObjectInner, ComObjectInterface, Error, IInspectable, IUnknownImpl as _, Result,
    implement,
};

#[implement(ISeparatorContextItem, IContextItem)]
pub struct SeparatorContextItem;

impl ISeparatorContextItem_Impl for SeparatorContextItem_Impl {}
impl IContextItem_Impl for SeparatorContextItem_Impl {}

#[implement(ICommandContextItem, IContextItem, ICommandItem, INotifyPropChanged)]
pub struct CommandContextItem<TC>
where
    TC: ComObjectInner + 'static,
    TC::Outer: ICommand_Impl + ComObjectInterface<ICommand>,
{
    cmd: ComObject<CommandItem<TC>>,
    critical: NotifyLock<bool>,
    shortcut: NotifyLock<Option<KeyChord>>,
}

impl<TC> CommandContextItem_Impl<TC>
where
    TC: ComObjectInner + 'static,
    TC::Outer: ICommand_Impl + ComObjectInterface<ICommand>,
{
    pub(crate) fn emit_self_prop_changed(&self, prop: &str) {
        let sender: IInspectable = self.to_interface();
        self.cmd.emit_prop_changed(&sender, prop);
    }

    pub fn critical(&self) -> Result<NotifyLockReadGuard<'_, bool>> {
        self.critical.read()
    }

    pub fn critical_mut(&self) -> Result<NotifyLockWriteGuard<'_, bool, impl Fn()>> {
        self.critical
            .write(|| self.emit_self_prop_changed("Critical"))
    }

    pub fn shortcut(&self) -> Result<NotifyLockReadGuard<'_, Option<KeyChord>>> {
        self.shortcut.read()
    }
    pub fn shortcut_mut(&self) -> Result<NotifyLockWriteGuard<'_, Option<KeyChord>, impl Fn()>> {
        self.shortcut
            .write(|| self.emit_self_prop_changed("RequestedShortcut"))
    }
}
impl<TC> ICommandContextItem_Impl for CommandContextItem_Impl<TC>
where
    TC: ComObjectInner + 'static,
    TC::Outer: ICommand_Impl + ComObjectInterface<ICommand>,
{
    fn IsCritical(&self) -> windows_core::Result<bool> {
        self.critical.read().map(|x| *x)
    }
    fn RequestedShortcut(&self) -> windows_core::Result<KeyChord> {
        self.shortcut
            .read()?
            .map(|x| x)
            .ok_or(Error::empty())
    }
}

impl<TC> ICommandItem_Impl for CommandContextItem_Impl<TC>
where
    TC: ComObjectInner + 'static,
    TC::Outer: ICommand_Impl + ComObjectInterface<ICommand>,
{
    ambassador_impl_ICommandItem_Impl! {
        body_struct(< >, ComObject<CommandItem<TC>>, cmd)
    }
}

impl<TC> IContextItem_Impl for CommandContextItem_Impl<TC>
where
    TC: ComObjectInner + 'static,
    TC::Outer: ICommand_Impl + ComObjectInterface<ICommand>,
{
}

impl<TC> INotifyPropChanged_Impl for CommandContextItem_Impl<TC>
where
    TC: ComObjectInner + 'static,
    TC::Outer: ICommand_Impl + ComObjectInterface<ICommand>,
{
    ambassador_impl_INotifyPropChanged_Impl! {
        body_struct(< >, ComObject<CommandItem<TC>>, cmd)
    }
}

pub enum ContextItem<TC>
where
    TC: ComObjectInner + 'static,
    TC::Outer: ICommand_Impl + ComObjectInterface<ICommand>,
{
    Separator(ComObject<SeparatorContextItem>),
    Command(ComObject<CommandContextItem<TC>>),
}

impl<TC> From<&ContextItem<TC>> for IContextItem
where
    TC: ComObjectInner + 'static,
    TC::Outer: ICommand_Impl + ComObjectInterface<ICommand>,
{
    fn from(item: &ContextItem<TC>) -> Self {
        match item {
            ContextItem::Separator(item) => item.to_interface(),
            ContextItem::Command(item) => item.to_interface(),
        }
    }
}