Skip to content

Initial checkin of CommunityWallClock and update WarpClock - #14

Open
KlausLoeffelmann wants to merge 20 commits into
mainfrom
Net11KioskModeDemos
Open

Initial checkin of CommunityWallClock and update WarpClock#14
KlausLoeffelmann wants to merge 20 commits into
mainfrom
Net11KioskModeDemos

Conversation

@KlausLoeffelmann

Copy link
Copy Markdown
Owner

This pull request introduces new documentation skills for WARP-DirectX features, updates the NuGet package version throughout the documentation, and clarifies usage and decision guidance for Direct2D/DirectWrite scenarios. It adds three new skill documents covering DirectX getting started, DirectComposition-exclusive top-level windows, and retained Visuals for animation/scene composition. Existing documentation is updated for clarity, accuracy, and to reference the new skills where appropriate.

New WARP-DirectX skills documentation:

  • Added warp-directx-getting-started skill covering Direct2D/DirectWrite fundamentals, base types (D2DPanel, D2DForm, D2DControl), the ID2DGraphics surface, render modes, and a decision table for next steps.
  • Added warp-directx-dcomp-exclusive-tlw skill for building fullscreen/kiosk/game windows with DirectComposition-exclusive rendering (D2DForm + UseDirectCompositionExclusiveRendering), including prerequisites, benefits, and minimal working example.
  • Added warp-directx-using-visuals skill explaining how to use retained DirectComposition Visuals for flicker-free animation, scene composition, and driving a render loop with a high-precision timer.

Documentation and decision guide improvements:

  • Updated .github/skills/WARP-ApiDecisionGuide/SKILL.md to reference the new DirectX skills in the feature table and in the skill index, clarifying when to use each DirectX-related skill. [1] [2]
  • Updated the preview NuGet version to 0.9.217-preview.gd29245666b throughout all relevant documentation. [1] [2] [3] [4] [5]

App services documentation update:

  • Improved metadata and versioning in warp-app-services skill, making required NuGet packages and their latest version explicit in the skill metadata.

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR adds a substantial new WinForms/.NET Direct2D + DirectComposition demo (“WARP DirectX Wall Clock”) with a plug-in theme model, plus a new KioskComponent demo app, and updates the repo’s Copilot skill documentation (including new DirectX skills and updated package-version references).

Changes:

  • Added the WarpClock demo: a Direct2D/DirectComposition clock engine (WarpClockControl), built-in themes, and drop-in plug-in theme loading.
  • Added the KioskComponent demo apps (CommunityWallClock + feature test harness).
  • Added/updated multiple Copilot skill documents (DirectX getting-started, DComp-exclusive TLW, visuals/animation loop, plus decision guide/version bumps) and refreshed the repo README featured section.

Reviewed changes

Copilot reviewed 73 out of 76 changed files in this pull request and generated 6 comments.

Show a summary per file
File Description
src/WinForms/NET11/WarpClock/WarpClock.Themes.Nerd/WarpClock.Themes.Nerd.csproj New “NERD” plug-in theme project.
src/WinForms/NET11/WarpClock/WarpClock.Themes.Nerd/NerdTheme.RadialLayout.cs Layout stub for the NerdTheme.
src/WinForms/NET11/WarpClock/WarpClock.Themes.Nerd/NerdTheme.NerdRenderer.cs Direct2D renderer for the NerdTheme visuals.
src/WinForms/NET11/WarpClock/WarpClock.Themes.Nerd/NerdTheme.cs NerdTheme IClockTheme implementation and element descriptors.
src/WinForms/NET11/WarpClock/WarpClock.Themes.LoseHour/WarpClock.Themes.LoseHour.csproj New Lose-Hour plug-in theme project.
src/WinForms/NET11/WarpClock/WarpClock.Themes.LoseHour/NeedleSpec.cs Hand geometry helper for Lose-Hour.
src/WinForms/NET11/WarpClock/WarpClock.Themes.LoseHour/LoseHourTheme.cs Lose-Hour IClockTheme (free-floating) + animator/layout.
src/WinForms/NET11/WarpClock/WarpClock.Themes.LoseHour/LoseHourRenderer.cs Direct2D renderer for Lose-Hour visuals.
src/WinForms/NET11/WarpClock/WarpClock.Themes.Builtin/WarpClock.Themes.Builtin.csproj Built-in theme pack project.
src/WinForms/NET11/WarpClock/WarpClock.Themes.Builtin/StandardClockTheme.cs Built-in theme wrapper around StandardClockDesign.
src/WinForms/NET11/WarpClock/WarpClock.Themes.Builtin/StandardClockRenderer.cs Renderer for built-in themes.
src/WinForms/NET11/WarpClock/WarpClock.Themes.Builtin/StandardClockDesign.cs Design record/enums for built-in theme styling.
src/WinForms/NET11/WarpClock/WarpClock.Themes.Builtin/RadialLayout.cs Default “defer to engine” radial layout implementation.
src/WinForms/NET11/WarpClock/WarpClock.Themes.Builtin/HandGeometry.cs Built-in hand silhouette generation.
src/WinForms/NET11/WarpClock/WarpClock.Themes.Builtin/BuiltInThemes.cs Factory for built-in theme instances.
src/WinForms/NET11/WarpClock/WarpClock.slnx Solution composition updated/added for WarpClock.
src/WinForms/NET11/WarpClock/WarpClock.Engine/WarpClockControl.cs Core DirectComposition-visual clock engine control.
src/WinForms/NET11/WarpClock/WarpClock.Engine/WarpClock.Engine.csproj WarpClock engine project.
src/WinForms/NET11/WarpClock/WarpClock.Engine/ThemeTickContext.cs Engine implementation of IClockTickContext.
src/WinForms/NET11/WarpClock/WarpClock.Engine/HandPointingSolver.cs Hand aiming + grace catch-up solver.
src/WinForms/NET11/WarpClock/WarpClock.Engine/ElementRuntime.cs Per-element runtime state for visuals and redraw caching.
src/WinForms/NET11/WarpClock/WarpClock.Engine/ElementRenderContext.cs Engine implementation of IClockRenderContext.
src/WinForms/NET11/WarpClock/WarpClock.Engine/DefaultClockLayout.cs Engine default radial anchor resolution.
src/WinForms/NET11/WarpClock/WarpClock.Engine/ClockTimeModel.cs Authoritative time snapshot model (offset/speed).
src/WinForms/NET11/WarpClock/WarpClock.Engine/ClockMath.cs Geometry helpers (angles/rotation/lerp).
src/WinForms/NET11/WarpClock/WarpClock.Engine/ClockHandMotion.cs Hand motion modes (crawl/sweep/tick).
src/WinForms/NET11/WarpClock/WarpClock.Engine/ClockGeometry.cs Surface geometry and design-unit scaling.
src/WinForms/NET11/WarpClock/WarpClock.App/WarpClock.App.csproj WarpClock host app project (copies plug-ins on build).
src/WinForms/NET11/WarpClock/WarpClock.App/ThemePluginLoader.cs Plug-in discovery/loading via collectible ALCs.
src/WinForms/NET11/WarpClock/WarpClock.App/Program.cs WarpClock app entry point.
src/WinForms/NET11/WarpClock/WarpClock.App/FormMain.ThemeEntry.cs Internal theme catalog entry model.
src/WinForms/NET11/WarpClock/WarpClock.App/FormMain.Designer.cs Main form Designer layout for WarpClock host.
src/WinForms/NET11/WarpClock/WarpClock.App/FormMain.cs WarpClock host behavior: menus, plug-in loading, kiosk wiring.
src/WinForms/NET11/WarpClock/WarpClock.Abstractions/WarpClock.Abstractions.csproj Plug-in contract project.
src/WinForms/NET11/WarpClock/WarpClock.Abstractions/ThemeCapabilities.cs Theme capability flags used by the engine.
src/WinForms/NET11/WarpClock/WarpClock.Abstractions/IThemeAnimator.cs Tick-driven theme animator contract.
src/WinForms/NET11/WarpClock/WarpClock.Abstractions/IClockTickContext.cs Animator tick context contract.
src/WinForms/NET11/WarpClock/WarpClock.Abstractions/IClockTheme.cs Theme contract (CreateElements, layout, renderer, animator).
src/WinForms/NET11/WarpClock/WarpClock.Abstractions/IClockRenderContext.cs Renderer draw context contract.
src/WinForms/NET11/WarpClock/WarpClock.Abstractions/IClockLayout.cs Anchor placement contract for themes.
src/WinForms/NET11/WarpClock/WarpClock.Abstractions/IClockElementRenderer.cs Per-element rendering contract.
src/WinForms/NET11/WarpClock/WarpClock.Abstractions/ClockTimeSnapshot.cs Authoritative time snapshot model for themes.
src/WinForms/NET11/WarpClock/WarpClock.Abstractions/ClockThemeExportAttribute.cs Optional plug-in metadata/opt-out attribute.
src/WinForms/NET11/WarpClock/WarpClock.Abstractions/ClockHandKind.cs Hand-kind enum used for time target selection.
src/WinForms/NET11/WarpClock/WarpClock.Abstractions/ClockElementParameters.cs Mutable per-element runtime parameters for animators.
src/WinForms/NET11/WarpClock/WarpClock.Abstractions/ClockElementKind.cs Element kinds (face, ticks, hands, drums, etc.).
src/WinForms/NET11/WarpClock/WarpClock.Abstractions/ClockElementId.cs Stable element identifier struct + helpers.
src/WinForms/NET11/WarpClock/WarpClock.Abstractions/ClockElementDescriptor.cs Element descriptor record (content size/pivot/zorder/redraw).
src/WinForms/NET11/WarpClock/README.md New WarpClock demo README.
src/WinForms/NET11/KioskComponent/KioskComponentFeatureTest/Program.cs Feature test app entry point for kiosk component.
src/WinForms/NET11/KioskComponent/KioskComponentFeatureTest/KioskComponentFeatureTest.csproj Feature test project file.
src/WinForms/NET11/KioskComponent/KioskComponentFeatureTest/Form1.resx Feature test form resources.
src/WinForms/NET11/KioskComponent/KioskComponentFeatureTest/Form1.Designer.cs Feature test form Designer wiring for kiosk component.
src/WinForms/NET11/KioskComponent/KioskComponentFeatureTest/Form1.cs Feature test wakeup handler (currently broken).
src/WinForms/NET11/KioskComponent/KioskComponent.slnx KioskComponent solution updated/added.
src/WinForms/NET11/KioskComponent/CommunityWallClock/CommunityWallClock/Program.cs CommunityWallClock DI/hosting bootstrap.
src/WinForms/NET11/KioskComponent/CommunityWallClock/CommunityWallClock/MainForm.resx CommunityWallClock form resources.
src/WinForms/NET11/KioskComponent/CommunityWallClock/CommunityWallClock/MainForm.Designer.cs CommunityWallClock form Designer file (contains non-Designer logic).
src/WinForms/NET11/KioskComponent/CommunityWallClock/CommunityWallClock/MainForm.cs CommunityWallClock form logic (currently uses legacy settings API).
src/WinForms/NET11/KioskComponent/CommunityWallClock/CommunityWallClock/CommunityWallClock.csproj CommunityWallClock project file.
src/WinForms/NET11/KioskComponent/CommunityWallClock/CommunityWallClock/appsettings.json CommunityWallClock app settings.
src/WinForms/NET11/KioskComponent/CommunityWallClock/.github/copilot-instructions.md Local Copilot guidance for that app (Designer vs regular code rules).
README.md Rotates featured demo to WarpClock and adds summary/link.
.github/skills/winforms-development/SKILL.md Adds guidance section about deferring heavy work from constructors.
.github/skills/winforms-designer-code/SKILL.md Adds note about keeping constructors cheap / handle creation timing.
.github/skills/WarpClock-ThemeAuthoring/SKILL.md New skill: generating WarpClock plug-in themes.
.github/skills/WARP-WinFormsControls/SKILL.md Updates referenced “current preview version”.
.github/skills/WARP-WinFormsAI/SKILL.md Updates referenced “current preview version”.
.github/skills/WARP-ToolStripIcons/SKILL.md Updates referenced “current preview version”.
.github/skills/WARP-Git-and-Github-API/SKILL.md Updates GitHub/Git skill doc package version snippet.
.github/skills/WARP-DirectX-Using-Visuals/SKILL.md New DirectX skill: retained visuals + animation loop.
.github/skills/WARP-DirectX-GettingStarted/SKILL.md New DirectX getting-started/decision skill.
.github/skills/WARP-DirectX-DComp-Exclusive-TLW/SKILL.md New DirectX skill: DComp-exclusive top-level windows.
.github/skills/WARP-binding-autoview/SKILL.md New/updated skill for AutoView + binding scaffolding.
.github/skills/WARP-AppServices/SKILL.md Updates skill metadata/versioning info.
.github/skills/WARP-ApiDecisionGuide/SKILL.md Updates decision guide with DirectX skill routing and version.
Files not reviewed (3)
  • src/WinForms/NET11/KioskComponent/CommunityWallClock/CommunityWallClock/MainForm.Designer.cs: Generated file
  • src/WinForms/NET11/KioskComponent/KioskComponentFeatureTest/Form1.Designer.cs: Generated file
  • src/WinForms/NET11/WarpClock/WarpClock.App/FormMain.Designer.cs: Generated file

Comment on lines +19 to +24
Bounds = _userSettingsService.GetSetting(
key: SettingsKey_MainFormBounds,
defaultValue: this.CenterToScreen(
horizontalFillGrade: 70,
verticalFillGrade: 70));
}
Comment on lines +30 to +35
_userSettingsService.SaveSetting(
key: SettingsKey_MainFormBounds,
value: Bounds);

_userSettingsService.Save();
}
Comment on lines +6 to +14
public partial class MainForm : Form, IServiceProvider
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;

private readonly IUserSettingsService _userSettingsService = null!;
private readonly IServiceProvider _serviceProvider = null!;
Comment on lines +62 to +73
object IServiceProvider.GetService(Type serviceType)
{
ArgumentNullException.ThrowIfNull(serviceType, nameof(serviceType));

if (_serviceProvider is null)
{
throw new InvalidOperationException("Service provider is not initialized.");
}

return _serviceProvider.GetService(serviceType)
?? throw new InvalidOperationException($"Service of type '{serviceType.Name}' is not registered.");
}
Comment on lines +12 to +16
private void KioskModeManager_Wakeup(object sender, KioskModeWakeupEventArgs e)
{
Debug.Print(e.)

}
Comment thread README.md
Comment on lines +5 to +12
## WARP DirectX Wall Clock — published Fri, Jun 19., 2026

The current featured demo is the **Layout Tester** — a WinForms .NET 10
The current featured demo is the **WARP DirectX Wall Clock** — a WinForms
.NET 11 analog clock where **every part (face, numerals, ticks, hands, arbour)
is its own DirectComposition visual**, composed by a small engine and styled by
**drop-in plug-in themes**. It doubles as a demo of the new .NET 11
`KioskModeManager` component (F11 fullscreen, taskbar hiding, sleep suppression,
wake events).
KlausLoeffelmann and others added 17 commits June 23, 2026 16:03
Enable Application.SetColorMode(SystemColorMode.System) so the WinForms
chrome (menu strip, status strip, dialogs) follows the OS theme. The
DirectX clock surface keeps rendering its own theme-specific colors.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
The kiosk manager starts with HideTaskbar = true, but the 'Hide taskbar
in kiosk' menu item was never checked at startup. Add RefreshKioskChecks()
to sync the menu check marks from the live manager state, so they are
correct on launch and cannot drift.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
The previous 'Sweep' motion was really a four-steps-per-second fast tick;
rename it to 'Fast Tick'. The new 'Sweep' is an ease-in-out glide that
swings to the next mark within a configurable GlideDurationSeconds (default
0.5s) and then rests on it.

Generalize HandPointingSolver.RadialTargetAngle so every hand honors its
motion (the old code only quantized the second hand). Add
WarpClockControl.GlideDurationSeconds and a 'Fast Tick' menu entry per hand.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Lay out the minute readout (6 bits) toward the tip (outer) and the hour
readout (5 bits) toward the pivot (inner), with a clear gap between the two
groups so the binary hour and minute can be told apart at a glance.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Delete the WarpClock.Themes.LoseHour sample plug-in (project, sources,
solution/host wiring) and drop ThemeCapabilities.VisibleHourCount, which
only existed to support it. The free-floating 'lose hours' base behavior is
superseded by the upcoming Magnetic Numerals feature.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Add WarpClockControl.MagneticNumerals: when on, every hand 'finds' the hour
numerals wherever a theme placed them and swings to the next one at its own
rate (second/minute/hour), gliding then tracking the live anchor so moving
numerals are followed. Numerals carry a tri-state ClockNumeralVisibility:
Visible (drawn + target), Transparent (hidden but still a target), Invisible
(hidden and skipped - the hand stays put). The engine hides non-Visible
visuals and a new MagneticNumeralSolver drives the aiming.

Expose the mode via a View menu toggle, and add the WarpClock.Themes.Scatter
sample plug-in that scatters/drifts the numerals to showcase the behavior.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
A garden-themed dial: a layered sunflower (two petal rings plus a
phyllotaxis seed head) for the face, twelve bee numerals that spin a full
360 degrees whenever a hand sweeps over them, and branch-shaped hands of
distinct sizes (stubby hour twig, leafy minute bough, long second shoot).
The bee spins are driven via ExtraRotationDegrees on the non-hand markers,
so the engine never has to bend the time-correctness rules.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
The SunFlowerTheme class file was never committed, so the plug-in assembly
shipped with only the renderer and animator and exposed no IClockTheme -
the loader therefore could not surface it in the Theme menu. Add the theme
class so SunFlower is discoverable and selectable.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…ral drift

Make the Scatter demo actually demonstrate magnetism: add a
ThemeCapabilities.MagneticByDefault hint that the host applies on theme
selection (magnetism stays a clock-control property the user can still
toggle). Scatter now starts in magnetic mode, so the hands sweep
number-to-number and follow the numerals instead of crawling 360.

Rework the numeral animation: numerals begin in their normal clock
positions and then wander, with at most four in motion at once, each easing
smoothly to a new spot and resting before moving again. One numeral cycles
to Invisible periodically so the hands visibly skip a missing numeral.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Move numerals within an annulus (~230..460 of the 500 dial) instead of
allowing radii as small as 70, so they stay away from the arbour and are
far less likely to overlap near the center.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
The animator was gated to a ~10 Hz cadence, so AnchorOffset-driven motion
(e.g. Scatter's wandering numerals) updated only ~10x/second and looked
choppy while the engine-driven hands ran at full frame rate. Drive the
animator once per rendered frame instead, so themed motion is as smooth as
the hands. Animators already integrate FrameDelta, so they need no changes.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
SunFlower -> Preeti Kurup, Scatter (Magnetic) -> Klaus Loeffelmann, and the
Nerd plug-in plus the built-in themes -> stock theme.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Add a View menu 'VSync' toggle bound to the control's VSyncEnabled (off by
default), and surface a smoothed frames-per-second value
(WarpClockControl.CurrentFramesPerSecond) in the status bar, refreshed by a
200 ms timer so it updates a few times a second without churning every frame.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Render a '{theme} - {author}' overlay on top of the dial, controllable via
two new WarpClockControl properties and a View > Theme info menu:

- RenderThemeInfo: Never, FixedPosition, FadeInAndOutAtFixedPosition,
  FadeAlternateScreenSides.
- ThemeInfoPlacement: LeftScreenSide (rotated 90 CCW), RightScreenSide
  (rotated 90 CW), OnClockFace (two centered lines: theme over author).

The fade modes reveal/erase the text character-by-character using a random
effect (first->last, last->first, mid->outer, outer->mid, fully random),
hold ~10s, fade out with a different effect; the alternating mode then waits
~5s and repeats on the other side. Drawn in the foreground Render pass and
cleared to transparent each frame so PreserveLastFrame can't freeze a faded
overlay while the retained hand/numeral visuals keep showing through.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
MeasureString trims trailing whitespace by default, so the prefix width for
the character after a space (e.g. 'Klaus ') dropped the space's width and
shifted every following glyph by one position ('KlausL oeffelmann'). Measure
prefixes with StringFormatFlags.MeasureTrailingSpaces so the space width is
preserved and the text lays out correctly.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
The previous MeasureTrailingSpaces fix only works for GDI+; WARP's
DirectWrite-backed ID2DGraphics.MeasureString ignores that flag and still
trims trailing whitespace, so the per-character layout kept shifting every
post-space glyph one slot early (e.g. 'RailwayC lassic- s tockt heme').

Measure each prefix with a sentinel glyph appended and subtract the
sentinel's own width. Trailing spaces become interior and are therefore
measured, independent of any trailing-whitespace flag or text engine.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Add an opt-in diagnostics overlay to quantify per-frame and resize cost:

- FrameMetrics / ResizeMeasurement records for per-frame and resize-burst timing
- WarpClockControl: DiagnosticsEnabled property plus FrameMeasured/ResizeMeasured
  events; per-phase Stopwatch timing (animator, element update, visual commit) and
  resize-burst aggregation, all gated so the hot path stays free when off
- FormMain: F12 toggle, throttled Consolas status readout, and a title-bar summary
- Reuse the engine's existing smoothed _framesPerSecond and drop the redundant
  _fpsTimer / _statusFps readout in favor of the richer F12 panel

Rebased onto origin/Net11KioskModeDemos; the skill relocation and CommunityWallClock
settings-API hunk from the original mis-targeted commit are intentionally omitted.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants