Initial checkin of CommunityWallClock and update WarpClock - #14
Open
KlausLoeffelmann wants to merge 20 commits into
Open
Initial checkin of CommunityWallClock and update WarpClock#14KlausLoeffelmann wants to merge 20 commits into
KlausLoeffelmann wants to merge 20 commits into
Conversation
There was a problem hiding this comment.
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 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). |
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>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
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:
warp-directx-getting-startedskill covering Direct2D/DirectWrite fundamentals, base types (D2DPanel,D2DForm,D2DControl), theID2DGraphicssurface, render modes, and a decision table for next steps.warp-directx-dcomp-exclusive-tlwskill for building fullscreen/kiosk/game windows with DirectComposition-exclusive rendering (D2DForm+UseDirectCompositionExclusiveRendering), including prerequisites, benefits, and minimal working example.warp-directx-using-visualsskill 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:
.github/skills/WARP-ApiDecisionGuide/SKILL.mdto reference the new DirectX skills in the feature table and in the skill index, clarifying when to use each DirectX-related skill. [1] [2]0.9.217-preview.gd29245666bthroughout all relevant documentation. [1] [2] [3] [4] [5]App services documentation update:
warp-app-servicesskill, making required NuGet packages and their latest version explicit in the skill metadata.