Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions crates/libs/composition/readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,9 @@ fn build(compositor: &Compositor) -> SpriteVisual {
}
```

Core types include `Compositor`, the visual types, brushes, shapes, and key-frame animations. For
system composition, create a `DispatcherQueueController` and `Compositor`, then host the root
visual with `Compositor::create_desktop_window_target`, which takes a
Core types include `Compositor`, the visual types, brushes, shapes, key-frame animations, and
animation groups. For system composition, create a `DispatcherQueueController` and `Compositor`,
then host the root visual with `Compositor::create_desktop_window_target`, which takes a
[`windows-window`][window-guide] `Window`. See the [composition
guide](https://github.com/microsoft/windows-rs/blob/master/docs/crates/windows-composition.md) for
the API and hosting options.
Expand Down
17 changes: 17 additions & 0 deletions crates/libs/composition/src/animation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,23 @@ impl Animation for Vector3KeyFrameAnimation {
}
}

/// A set of animations that start together.
#[derive(Clone)]
pub struct CompositionAnimationGroup(pub(crate) bindings::CompositionAnimationGroup);

impl CompositionAnimationGroup {
/// Adds an animation to the group.
pub fn add(&self, animation: &impl Animation) {
self.0.Add(&animation.as_animation().0).unwrap();
}

/// Returns the lifted group as an inspectable object for a WinUI host.
#[cfg(feature = "reactor")]
pub fn as_host(&self) -> windows_core::IInspectable {
self.0.cast().unwrap()
}
}

/// A map of property-name -> animation applied to a visual so that changes to
/// those properties animate automatically.
///
Expand Down
79 changes: 78 additions & 1 deletion crates/libs/composition/src/bindings.rs
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,38 @@ impl windows_core::RuntimeName for CompositionAnimation {
unsafe impl Send for CompositionAnimation {}
unsafe impl Sync for CompositionAnimation {}
#[repr(transparent)]
#[derive(Clone, Debug, Eq, PartialEq)]
pub struct CompositionAnimationGroup(windows_core::IUnknown);
windows_core::imp::interface_hierarchy!(
CompositionAnimationGroup,
windows_core::IUnknown,
windows_core::IInspectable
);
windows_core::imp::required_hierarchy!(
CompositionAnimationGroup,
ICompositionAnimationBase,
CompositionObject
);
impl windows_core::RuntimeType for CompositionAnimationGroup {
const SIGNATURE: windows_core::imp::ConstBuffer =
windows_core::imp::ConstBuffer::for_class::<Self, ICompositionAnimationGroup>();
}
unsafe impl windows_core::Interface for CompositionAnimationGroup {
type Vtable = <ICompositionAnimationGroup as windows_core::Interface>::Vtable;
const IID: windows_core::GUID = <ICompositionAnimationGroup as windows_core::Interface>::IID;
}
impl core::ops::Deref for CompositionAnimationGroup {
type Target = ICompositionAnimationGroup;
fn deref(&self) -> &Self::Target {
unsafe { core::mem::transmute(self) }
}
}
impl windows_core::RuntimeName for CompositionAnimationGroup {
const NAME: &'static str = "Windows.UI.Composition.CompositionAnimationGroup";
}
unsafe impl Send for CompositionAnimationGroup {}
unsafe impl Sync for CompositionAnimationGroup {}
#[repr(transparent)]
#[derive(Clone, Copy, Debug, Default, Eq, PartialEq)]
pub struct CompositionBatchTypes(pub u32);
impl CompositionBatchTypes {
Expand Down Expand Up @@ -1002,6 +1034,38 @@ impl ICompositionAnimationBase_Vtbl {
pub struct ICompositionAnimationBase_Vtbl {
pub base__: windows_core::IInspectable_Vtbl,
}
windows_core::imp::define_interface!(
ICompositionAnimationGroup,
ICompositionAnimationGroup_Vtbl,
0x5e7cc90c_cd14_4e07_8a55_c72527aabdac
);
impl windows_core::RuntimeType for ICompositionAnimationGroup {
const SIGNATURE: windows_core::imp::ConstBuffer =
windows_core::imp::ConstBuffer::for_interface::<Self>();
}
impl ICompositionAnimationGroup {
pub(crate) fn Add<P0>(&self, value: P0) -> windows_core::Result<()>
where
P0: windows_core::Param<CompositionAnimation>,
{
unsafe {
(windows_core::Interface::vtable(self).Add)(
windows_core::Interface::as_raw(self),
value.param().abi(),
)
.ok()
}
}
}
#[repr(C)]
pub struct ICompositionAnimationGroup_Vtbl {
pub base__: windows_core::IInspectable_Vtbl,
Count: usize,
pub Add: unsafe extern "system" fn(
*mut core::ffi::c_void,
*mut core::ffi::c_void,
) -> windows_core::HRESULT,
}
windows_core::imp::define_interface!(
ICompositionBrush,
ICompositionBrush_Vtbl,
Expand Down Expand Up @@ -1792,6 +1856,16 @@ impl windows_core::RuntimeType for ICompositor2 {
windows_core::imp::ConstBuffer::for_interface::<Self>();
}
impl ICompositor2 {
pub(crate) fn CreateAnimationGroup(&self) -> windows_core::Result<CompositionAnimationGroup> {
unsafe {
let mut result__ = core::mem::zeroed();
(windows_core::Interface::vtable(self).CreateAnimationGroup)(
windows_core::Interface::as_raw(self),
&mut result__,
)
.and_then(|| windows_core::Type::from_abi(result__))
}
}
pub(crate) fn CreateImplicitAnimationCollection(
&self,
) -> windows_core::Result<ImplicitAnimationCollection> {
Expand Down Expand Up @@ -1819,7 +1893,10 @@ impl ICompositor2 {
pub struct ICompositor2_Vtbl {
pub base__: windows_core::IInspectable_Vtbl,
CreateAmbientLight: usize,
CreateAnimationGroup: usize,
pub CreateAnimationGroup: unsafe extern "system" fn(
*mut core::ffi::c_void,
*mut *mut core::ffi::c_void,
) -> windows_core::HRESULT,
CreateBackdropBrush: usize,
CreateDistantLight: usize,
CreateDropShadow: usize,
Expand Down
79 changes: 78 additions & 1 deletion crates/libs/composition/src/bindings_lifted.rs
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,38 @@ impl windows_core::RuntimeName for CompositionAnimation {
unsafe impl Send for CompositionAnimation {}
unsafe impl Sync for CompositionAnimation {}
#[repr(transparent)]
#[derive(Clone, Debug, Eq, PartialEq)]
pub struct CompositionAnimationGroup(windows_core::IUnknown);
windows_core::imp::interface_hierarchy!(
CompositionAnimationGroup,
windows_core::IUnknown,
windows_core::IInspectable
);
windows_core::imp::required_hierarchy!(
CompositionAnimationGroup,
ICompositionAnimationBase,
CompositionObject
);
impl windows_core::RuntimeType for CompositionAnimationGroup {
const SIGNATURE: windows_core::imp::ConstBuffer =
windows_core::imp::ConstBuffer::for_class::<Self, ICompositionAnimationGroup>();
}
unsafe impl windows_core::Interface for CompositionAnimationGroup {
type Vtable = <ICompositionAnimationGroup as windows_core::Interface>::Vtable;
const IID: windows_core::GUID = <ICompositionAnimationGroup as windows_core::Interface>::IID;
}
impl core::ops::Deref for CompositionAnimationGroup {
type Target = ICompositionAnimationGroup;
fn deref(&self) -> &Self::Target {
unsafe { core::mem::transmute(self) }
}
}
impl windows_core::RuntimeName for CompositionAnimationGroup {
const NAME: &'static str = "Microsoft.UI.Composition.CompositionAnimationGroup";
}
unsafe impl Send for CompositionAnimationGroup {}
unsafe impl Sync for CompositionAnimationGroup {}
#[repr(transparent)]
#[derive(Clone, Copy, Debug, Default, Eq, PartialEq)]
pub struct CompositionBatchTypes(pub u32);
impl CompositionBatchTypes {
Expand Down Expand Up @@ -645,6 +677,38 @@ impl ICompositionAnimationBase_Vtbl {
pub struct ICompositionAnimationBase_Vtbl {
pub base__: windows_core::IInspectable_Vtbl,
}
windows_core::imp::define_interface!(
ICompositionAnimationGroup,
ICompositionAnimationGroup_Vtbl,
0xa51cdcac_b972_5ae7_81d0_9d91c71ecb7a
);
impl windows_core::RuntimeType for ICompositionAnimationGroup {
const SIGNATURE: windows_core::imp::ConstBuffer =
windows_core::imp::ConstBuffer::for_interface::<Self>();
}
impl ICompositionAnimationGroup {
pub(crate) fn Add<P0>(&self, value: P0) -> windows_core::Result<()>
where
P0: windows_core::Param<CompositionAnimation>,
{
unsafe {
(windows_core::Interface::vtable(self).Add)(
windows_core::Interface::as_raw(self),
value.param().abi(),
)
.ok()
}
}
}
#[repr(C)]
pub struct ICompositionAnimationGroup_Vtbl {
pub base__: windows_core::IInspectable_Vtbl,
Count: usize,
pub Add: unsafe extern "system" fn(
*mut core::ffi::c_void,
*mut core::ffi::c_void,
) -> windows_core::HRESULT,
}
windows_core::imp::define_interface!(
ICompositionBrush,
ICompositionBrush_Vtbl,
Expand Down Expand Up @@ -1211,6 +1275,16 @@ impl windows_core::RuntimeType for ICompositor2 {
windows_core::imp::ConstBuffer::for_interface::<Self>();
}
impl ICompositor2 {
pub(crate) fn CreateAnimationGroup(&self) -> windows_core::Result<CompositionAnimationGroup> {
unsafe {
let mut result__ = core::mem::zeroed();
(windows_core::Interface::vtable(self).CreateAnimationGroup)(
windows_core::Interface::as_raw(self),
&mut result__,
)
.and_then(|| windows_core::Type::from_abi(result__))
}
}
pub(crate) fn CreateImplicitAnimationCollection(
&self,
) -> windows_core::Result<ImplicitAnimationCollection> {
Expand Down Expand Up @@ -1238,7 +1312,10 @@ impl ICompositor2 {
pub struct ICompositor2_Vtbl {
pub base__: windows_core::IInspectable_Vtbl,
CreateAmbientLight: usize,
CreateAnimationGroup: usize,
pub CreateAnimationGroup: unsafe extern "system" fn(
*mut core::ffi::c_void,
*mut *mut core::ffi::c_void,
) -> windows_core::HRESULT,
CreateBackdropBrush: usize,
CreateDistantLight: usize,
CreateDropShadow: usize,
Expand Down
6 changes: 6 additions & 0 deletions crates/libs/composition/src/compositor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,12 @@ impl Compositor {
Vector3KeyFrameAnimation(self.0.CreateVector3KeyFrameAnimation().unwrap())
}

/// Creates an empty group whose animations start together.
pub fn create_animation_group(&self) -> CompositionAnimationGroup {
let compositor: bindings::ICompositor2 = self.0.cast().unwrap();
CompositionAnimationGroup(compositor.CreateAnimationGroup().unwrap())
}

/// Creates a scalar (`f32`) key-frame animation.
pub fn create_scalar_key_frame_animation(&self) -> ScalarKeyFrameAnimation {
ScalarKeyFrameAnimation(self.0.CreateScalarKeyFrameAnimation().unwrap())
Expand Down
4 changes: 2 additions & 2 deletions crates/libs/composition/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -59,8 +59,8 @@ pub(crate) use sealed::Sealed;
pub(crate) use windows_core::Interface;

pub use animation::{
Animation, CompositionAnimation, CompositionEasingFunction, ImplicitAnimationCollection,
ScalarKeyFrameAnimation, Vector3KeyFrameAnimation,
Animation, CompositionAnimation, CompositionAnimationGroup, CompositionEasingFunction,
ImplicitAnimationCollection, ScalarKeyFrameAnimation, Vector3KeyFrameAnimation,
};
pub use batch::{BatchKind, CompositionScopedBatch};
pub use brush::{Brush, CompositionBrush, CompositionColorBrush, CompositionNineGridBrush};
Expand Down
57 changes: 57 additions & 0 deletions crates/libs/reactor/readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,3 +35,60 @@ builders convert to `Element` with `.into()`. `cx.use_state` returns the current
whose `call` schedules a rerender. `ReactorWindow` opens more top-level windows. See the [reactor
guide](https://github.com/microsoft/windows-rs/blob/master/docs/crates/windows-reactor.md) for
components, hooks, layout, styling, and widgets.

WinUI lightweight styling resources use typed values:

```rust,ignore
button("Delete").resource_overrides(|resources| {
resources
.set("ButtonBackground", Color::rgb(178, 34, 34))
.set("ButtonBorderThemeThickness", Thickness::uniform(0.0))
.set("ControlCornerRadius", CornerRadius::uniform(8.0))
})
```

Replacing or clearing the builder removes only the resource keys previously owned by Reactor.

`PointerEventInfo` reports both element-local `x`/`y` coordinates and stable window-relative
`window_x`/`window_y` coordinates for drag calculations whose target moves during the gesture.
Use `.capture_pointer_on_press()` for drag handles that must keep receiving moves outside their
hit-test bounds, and clear drag state from capture-lost and canceled callbacks.

`NavigationView` can keep pane state controlled and react to its actual responsive display mode:

```rust,ignore
NavigationView::new(items, content)
.pane_open(pane_open)
.on_pane_open_changed(set_pane_open)
.pane_display_mode(NavigationViewPaneDisplayMode::Auto)
.on_display_mode_changed(set_display_mode)
```

The callbacks report settled WinUI dependency-property values rather than pane transition intent.

Lifecycle transitions run when an element enters or leaves the WinUI visual tree:

```rust,ignore
button("Animated").transition(
Some(AnimationConfig::fade_in(Duration::from_millis(200))),
Some(AnimationConfig::fade_out(Duration::from_millis(300))),
)
```

Reactor removes the logical element immediately while WinUI Composition keeps the departing visual
alive until its exit animation finishes. See the `exit_transition` sample.

`TabItem::with_key` supplies the identity returned by `TabView::on_close_requested`. Key changes,
including removal, update the existing native item without leaving stale close-callback identity.
See the `tab_view_item_key` sample.

Icon-taking controls share one `Icon` model:

```rust,ignore
button("Confirm").icon(Icon::path("F1 M 0,8 L 6,14 L 16,2 L 14,0 L 6,10 L 2,6 Z"));
button("Mask").icon(Icon::bitmap_icon("ms-appx:///Assets/mask.png", true));
button("Logo").icon(Icon::image("ms-appx:///Assets/logo.svg"));
```

`bitmap_icon` uses WinUI `BitmapIcon` and makes monochrome rendering explicit. `image` uses
full-color `ImageIcon` and accepts raster, SVG, or surface sources.
Loading
Loading