Skip to content

Commit 5f68260

Browse files
committed
sample: add auto-refresh toggle for external rotation mode
Demonstrates Combobulate.EnableAutoRefresh wired against the same CompositionPropertySet the external rotation expression already drives. Sampler also pumps CombobulateSceneVisual.RebuildForExternalRotation each tick so both side-by-side renderers stay in sync.
1 parent ee4259f commit 5f68260

2 files changed

Lines changed: 45 additions & 1 deletion

File tree

src/Combobulate.Sample.WinUI3/MainWindow.xaml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,11 @@
4848
<Button Content="Refresh quads"
4949
Click="RefreshQuads_Click"
5050
ToolTipService.ToolTip="External-mode helper. Re-runs back-face cull / painter sort (Combobulate) and re-bakes mesh (CombobulateSceneVisual) for the current slider rotation."/>
51+
<ToggleSwitch x:Name="AutoRefreshToggle"
52+
OnContent="Auto-refresh"
53+
OffContent="Manual refresh"
54+
Toggled="AutoRefreshToggle_Toggled"
55+
ToolTipService.ToolTip="Only meaningful in external rotation mode. When ON, subscribes to CompositionTarget.Rendering and feeds the live property-set value into RebuildForExternalRotation per UI tick — painter sort and back-face cull stay in sync as the model spins, no manual Refresh needed."/>
5156
<TextBlock x:Name="StatusText"
5257
VerticalAlignment="Center"
5358
Opacity="0.7"

src/Combobulate.Sample.WinUI3/MainWindow.xaml.cs

Lines changed: 40 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,46 @@ private void ResetRotation_Click(object sender, RoutedEventArgs e)
5353

5454
private void Rotation_ValueChanged(object sender, RangeBaseValueChangedEventArgs e) => ApplyRotation();
5555

56-
private void ExternalRotationToggle_Toggled(object sender, RoutedEventArgs e) => ApplyRotation();
56+
private void ExternalRotationToggle_Toggled(object sender, RoutedEventArgs e)
57+
{
58+
ApplyRotation();
59+
UpdateAutoRefresh();
60+
}
61+
62+
private void AutoRefreshToggle_Toggled(object sender, RoutedEventArgs e) => UpdateAutoRefresh();
63+
64+
/// <summary>
65+
/// Auto-refresh only makes sense in external-rotation mode (in internal mode each
66+
/// rotation DP setter already triggers a Rebuild on the UI thread). When both
67+
/// toggles are on, subscribe Combobulate to <c>CompositionTarget.Rendering</c> via
68+
/// <c>EnableAutoRefresh</c> with a sampler that reads the live property set the
69+
/// expression animation already drives. The sampler also pokes the SceneVisual
70+
/// renderer's <c>RebuildForExternalRotation</c> so both side-by-side views stay
71+
/// in sync as the value updates from any thread.
72+
/// </summary>
73+
private void UpdateAutoRefresh()
74+
{
75+
if (combobulate == null) return;
76+
bool external = ExternalRotationToggle?.IsOn == true;
77+
bool wantAuto = external && AutoRefreshToggle?.IsOn == true;
78+
79+
if (wantAuto)
80+
{
81+
var (props, _) = GetOrCreateExternalRotation();
82+
combobulate.EnableAutoRefresh(() =>
83+
{
84+
props.TryGetVector3("Rotation", out var r);
85+
// CombobulateSceneVisual doesn't have its own auto-refresh hook yet,
86+
// so piggy-back the same per-frame tick to keep its mesh in sync.
87+
combobulateSceneVisual.RebuildForExternalRotation(r);
88+
return r;
89+
});
90+
}
91+
else
92+
{
93+
combobulate.DisableAutoRefresh();
94+
}
95+
}
5796

5897
private void RefreshQuads_Click(object sender, RoutedEventArgs e)
5998
{

0 commit comments

Comments
 (0)