use crate::bindings::*;
use crate::notify::*;
use crate::utils::ComBuilder;
use std::sync::RwLock;
use windows::Win32::Foundation::E_INVALIDARG;
use windows_core::AgileReference;
use windows_core::{ComObject, IInspectable, IUnknownImpl as _, implement};
pub(crate) static EXTENSION_HOST: RwLock<Option<AgileReference<IExtensionHost>>> =
RwLock::new(None);
#[doc = include_str!("./bindings_docs/IProgressState.md")]
#[implement(IProgressState, INotifyPropChanged)]
pub struct ProgressState {
indeterminate: NotifyLock<bool>,
percentage: NotifyLock<u32>,
event: PropChangedEventHandler,
}
pub struct ProgressStateBuilder {
indeterminate: bool,
percentage: u32,
}
impl ProgressStateBuilder {
pub fn new() -> Self {
ProgressStateBuilder {
indeterminate: true,
percentage: 0,
}
}
pub fn indeterminate(mut self, indeterminate: bool) -> Self {
self.indeterminate = indeterminate;
self
}
pub fn percentage(mut self, percentage: u32) -> Self {
self.percentage = percentage;
self
}
}
impl ComBuilder for ProgressStateBuilder {
type Output = ProgressState;
fn build_unmanaged(self) -> Self::Output {
ProgressState {
indeterminate: NotifyLock::new(self.indeterminate),
percentage: NotifyLock::new(self.percentage),
event: PropChangedEventHandler::new(),
}
}
}
impl ProgressState_Impl {
pub(crate) fn emit_self_prop_changed(&self, prop: &str) {
let sender: IInspectable = self.to_interface();
let arg: IPropChangedEventArgs = PropChangedEventArgs(prop.into()).into();
self.event.call(|handler| handler.Invoke(&sender, &arg));
}
#[doc = include_str!("./bindings_docs/IProgressState/IsIndeterminate.md")]
pub fn indeterminate(&self) -> windows_core::Result<NotifyLockReadGuard<'_, bool>> {
self.indeterminate.read()
}
#[doc = include_str!("./bindings_docs/IProgressState/IsIndeterminate.md")]
pub fn indeterminate_mut(&self) -> windows_core::Result<NotifyLockWriteGuard<'_, bool>> {
self.indeterminate
.write(|| self.emit_self_prop_changed("IsIndeterminate"))
}
#[doc = include_str!("./bindings_docs/IProgressState/ProgressPercent.md")]
pub fn percentage(&self) -> windows_core::Result<NotifyLockReadGuard<'_, u32>> {
self.percentage.read()
}
#[doc = include_str!("./bindings_docs/IProgressState/ProgressPercent.md")]
pub fn percentage_mut(&self) -> windows_core::Result<NotifyLockWriteGuard<'_, u32>> {
self.percentage
.write(|| self.emit_self_prop_changed("ProgressPercent"))
}
}
impl INotifyPropChanged_Impl for ProgressState_Impl {
fn PropChanged(
&self,
handler: windows_core::Ref<
'_,
windows::Foundation::TypedEventHandler<
windows_core::IInspectable,
IPropChangedEventArgs,
>,
>,
) -> windows_core::Result<i64> {
self.event.add(handler.ok()?)
}
fn RemovePropChanged(&self, token: i64) -> windows_core::Result<()> {
self.event.remove(token);
Ok(())
}
}
impl IProgressState_Impl for ProgressState_Impl {
fn IsIndeterminate(&self) -> windows_core::Result<bool> {
self.indeterminate.read().map(|x| *x)
}
fn ProgressPercent(&self) -> windows_core::Result<u32> {
self.percentage.read().map(|x| *x)
}
}
#[doc = include_str!("./bindings_docs/MessageState.md")]
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum MessageState {
#[doc = include_str!("./bindings_docs/MessageState/Info.md")]
Info,
#[doc = include_str!("./bindings_docs/MessageState/Success.md")]
Success,
#[doc = include_str!("./bindings_docs/MessageState/Warning.md")]
Warning,
#[doc = include_str!("./bindings_docs/MessageState/Error.md")]
Error,
}
impl TryFrom<crate::bindings::MessageState> for MessageState {
type Error = windows_core::Error;
fn try_from(value: crate::bindings::MessageState) -> Result<Self, windows_core::Error> {
match value {
crate::bindings::MessageState::Error => Ok(MessageState::Error),
crate::bindings::MessageState::Warning => Ok(MessageState::Warning),
crate::bindings::MessageState::Info => Ok(MessageState::Info),
crate::bindings::MessageState::Success => Ok(MessageState::Success),
_ => Err(E_INVALIDARG.into()),
}
}
}
impl From<MessageState> for crate::bindings::MessageState {
fn from(value: MessageState) -> Self {
match value {
MessageState::Error => crate::bindings::MessageState::Error,
MessageState::Warning => crate::bindings::MessageState::Warning,
MessageState::Info => crate::bindings::MessageState::Info,
MessageState::Success => crate::bindings::MessageState::Success,
}
}
}
#[doc = include_str!("./bindings_docs/StatusContext.md")]
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum StatusContext {
#[doc = include_str!("./bindings_docs/StatusContext/Page.md")]
Page,
#[doc = include_str!("./bindings_docs/StatusContext/Extension.md")]
Extension,
}
impl TryFrom<crate::bindings::StatusContext> for StatusContext {
type Error = windows_core::Error;
fn try_from(value: crate::bindings::StatusContext) -> Result<Self, windows_core::Error> {
match value {
crate::bindings::StatusContext::Page => Ok(StatusContext::Page),
crate::bindings::StatusContext::Extension => Ok(StatusContext::Extension),
_ => Err(E_INVALIDARG.into()),
}
}
}
impl From<StatusContext> for crate::bindings::StatusContext {
fn from(value: StatusContext) -> Self {
match value {
StatusContext::Page => crate::bindings::StatusContext::Page,
StatusContext::Extension => crate::bindings::StatusContext::Extension,
}
}
}
#[doc = include_str!("./bindings_docs/IStatusMessage.md")]
#[implement(IStatusMessage, INotifyPropChanged)]
pub struct StatusMessage {
state: NotifyLock<MessageState>,
progress: NotifyLock<ComObject<ProgressState>>,
message: NotifyLock<windows_core::HSTRING>,
event: PropChangedEventHandler,
}
pub struct StatusMessageBuilder {
state: MessageState,
progress: ComObject<ProgressState>,
message: windows_core::HSTRING,
}
impl StatusMessageBuilder {
pub fn new() -> Self {
StatusMessageBuilder {
state: MessageState::Info,
progress: ProgressStateBuilder::new().build(),
message: windows_core::HSTRING::default(),
}
}
pub fn state(mut self, state: MessageState) -> Self {
self.state = state;
self
}
pub fn progress(mut self, progress: ComObject<ProgressState>) -> Self {
self.progress = progress;
self
}
pub fn message(mut self, message: windows_core::HSTRING) -> Self {
self.message = message;
self
}
pub fn build(self) -> StatusMessage {
StatusMessage {
state: NotifyLock::new(self.state),
progress: NotifyLock::new(self.progress),
message: NotifyLock::new(self.message),
event: PropChangedEventHandler::new(),
}
}
}
impl StatusMessage_Impl {
pub(crate) fn emit_self_prop_changed(&self, prop: &str) {
let sender: IInspectable = self.to_interface();
let arg: IPropChangedEventArgs = PropChangedEventArgs(prop.into()).into();
self.event.call(|handler| handler.Invoke(&sender, &arg));
}
#[doc = include_str!("./bindings_docs/IStatusMessage/State.md")]
pub fn state(&self) -> windows_core::Result<NotifyLockReadGuard<'_, MessageState>> {
self.state.read()
}
#[doc = include_str!("./bindings_docs/IStatusMessage/State.md")]
pub fn state_mut(&self) -> windows_core::Result<NotifyLockWriteGuard<'_, MessageState>> {
self.state.write(|| self.emit_self_prop_changed("State"))
}
#[doc = include_str!("./bindings_docs/IStatusMessage/Progress.md")]
pub fn progress(
&self,
) -> windows_core::Result<NotifyLockReadGuard<'_, ComObject<ProgressState>>> {
self.progress.read()
}
#[doc = include_str!("./bindings_docs/IStatusMessage/Progress.md")]
pub fn progress_mut(
&self,
) -> windows_core::Result<NotifyLockWriteGuard<'_, ComObject<ProgressState>>> {
self.progress
.write(|| self.emit_self_prop_changed("Progress"))
}
#[doc = include_str!("./bindings_docs/IStatusMessage/Message.md")]
pub fn message(&self) -> windows_core::Result<NotifyLockReadGuard<'_, windows_core::HSTRING>> {
self.message.read()
}
#[doc = include_str!("./bindings_docs/IStatusMessage/Message.md")]
pub fn message_mut(
&self,
) -> windows_core::Result<NotifyLockWriteGuard<'_, windows_core::HSTRING>> {
self.message
.write(|| self.emit_self_prop_changed("Message"))
}
}
impl IStatusMessage_Impl for StatusMessage_Impl {
fn State(&self) -> windows_core::Result<crate::bindings::MessageState> {
self.state.read().map(|x| x.clone().into())
}
fn Progress(&self) -> windows_core::Result<IProgressState> {
self.progress.read().map(|x| x.to_interface())
}
fn Message(&self) -> windows_core::Result<windows_core::HSTRING> {
self.message.read().map(|x| x.clone())
}
}
impl INotifyPropChanged_Impl for StatusMessage_Impl {
fn PropChanged(
&self,
handler: windows_core::Ref<
'_,
windows::Foundation::TypedEventHandler<
windows_core::IInspectable,
IPropChangedEventArgs,
>,
>,
) -> windows_core::Result<i64> {
self.event.add(handler.ok()?)
}
fn RemovePropChanged(&self, token: i64) -> windows_core::Result<()> {
self.event.remove(token);
Ok(())
}
}
#[doc = include_str!("./bindings_docs/ILogMessage.md")]
#[implement(ILogMessage)]
#[derive(Debug, Clone)]
pub struct LogMessage {
#[doc = include_str!("./bindings_docs/ILogMessage/State.md")]
pub state: MessageState,
#[doc = include_str!("./bindings_docs/ILogMessage/Message.md")]
pub message: windows_core::HSTRING,
}
impl LogMessage {
pub fn new(state: MessageState, message: windows_core::HSTRING) -> Self {
LogMessage { state, message }
}
pub fn info(message: windows_core::HSTRING) -> Self {
LogMessage::new(MessageState::Info, message)
}
pub fn success(message: windows_core::HSTRING) -> Self {
LogMessage::new(MessageState::Success, message)
}
pub fn warning(message: windows_core::HSTRING) -> Self {
LogMessage::new(MessageState::Warning, message)
}
pub fn error(message: windows_core::HSTRING) -> Self {
LogMessage::new(MessageState::Error, message)
}
pub fn log(self) {
let ilog: ILogMessage = self.into();
log_message(ilog);
}
}
impl ILogMessage_Impl for LogMessage_Impl {
fn State(&self) -> windows_core::Result<crate::bindings::MessageState> {
Ok(self.state.clone().into())
}
fn Message(&self) -> windows_core::Result<windows_core::HSTRING> {
Ok(self.message.clone())
}
}
pub fn set_ext_host(host: &IExtensionHost) {
let reference = AgileReference::new(host).unwrap();
if let Ok(mut lock) = EXTENSION_HOST.write() {
*lock = Some(reference);
}
}
pub fn show_status(message: ComObject<StatusMessage>, context: StatusContext) {
if let Ok(lock) = EXTENSION_HOST.read() {
if let Some(host) = lock.as_ref().and_then(|x| x.resolve().ok()) {
let _ = host.ShowStatus(message.as_interface(), context.into());
}
}
}
pub fn hide_status(message: ComObject<StatusMessage>) {
if let Ok(lock) = EXTENSION_HOST.read() {
if let Some(host) = lock.as_ref().and_then(|x| x.resolve().ok()) {
let _ = host.HideStatus(message.as_interface());
}
}
}
pub fn log_message(message: impl std::borrow::Borrow<ILogMessage>) {
if let Ok(lock) = EXTENSION_HOST.read() {
if let Some(host) = lock.as_ref().and_then(|x| x.resolve().ok()) {
let _ = host.LogMessage(message.borrow());
}
}
}