Files
LlamaCasty/Models/index.md
T
gramps 6271bf34c9 TASK 60: the border-colour drop-down names every colour
The creator: "under Live->Layers->webcam->Properties->border color: in the drop
down box, the #hex values are good, but add a corresponding color name/label next
to the value."

Each row now reads "#e94560  Crimson" - the hex stays exactly as it was, the
colour's name goes next to it (dimmed #a0a0b0 so the hex reads first), and the
tooltip becomes "Crimson (#e94560)".

The 14 colours were a hard-coded string[] inside the click handler - a list of
bare strings cannot carry a name, and a list hidden in UI code cannot be asserted
on. They now live in Models/BorderColorPalette.cs: NamedColor(Hex, Name) +
BorderColorPalette.All (the single source of truth) + NameOf(hex), which answers
case-insensitively and falls back to the hex for a colour outside the palette.
The picker builds its menu from the catalogue and no longer knows any colour by
heart.

The names are chosen not to collide - the palette has two greens, two blues and
two warm colours: #00FF00 is Lime and #22c55e Emerald, #0000FF is Blue and
#3b82f6 Azure, #FF8800 is Orange and #f59e0b Amber.

Guard: ytLive.Tests/BorderColorPaletteTests.cs - every entry valid + named, no
hex or name repeated, the 14 legacy colours all still offered, NameOf answers,
and the old list is gone from the handler. 433/433 green, 0 warnings.
2026-10-21 20:03:19 -07:00

7.5 KiB
Raw Blame History

Models — index

Plain data types. No logic beyond what a property can carry. See schema.md for the memory-map conventions.

File Purpose
Scene.cs A scene: Name, IsHidden, IsChatScene, IsEditing, HasBackdrop (Live-only policy flag, default off — only the canonical Live scene has one, see SceneCatalog), Elements collection (images + webcam config), WebcamConfig accessor
SceneCatalog.cs The five canonical scenes (Starting/Live/BRB/Chat/Ending) — the product, by name: All, IsCanonical, Is(name, canonical) (case-insensitive trim), IsChat, HasBackdrop(name) (true only for Live). Drives the empty-DB seed, the "+" missing-scenes menu, and MainViewModel.EnforceBackdropPolicy
Source.cs A source: SourceType enum (DisplayCapture/WindowCapture/Background/Image/TextOverlay/ChatBox/Countdown/WebSource/MediaSource/AlertBox (TASK 43 — the celebration zone, one per layout) — Webcam removed), X/Y/Width/Height, Opacity, IsEnabled, ImageSource (static) / VideoImageSource (live frames), DisplaySource (IsLiveCapture → video, else static), ClipShape enum (Traditional/Round), IsMirrored + MirrorScale, MirrorButtonText, asset identity, IsImageSource (XAML binds this, never Type), backdrop surface: IsBackdrop (permanent bottom layer, never removable), CaptureKey (persisted monitor:<n>/window:<hwnd>/picker:<name>), IsLiveCapture (Type is Display/WindowCapture)
SceneElement.cs Base for anything placeable in a scene: shared layout/clip/mirror/border surface, virtual IsWebcam/virtual IsImageSource/virtual IsZoomLayer (TASK 52); ToggleClipShape + persisted RectWidth/RectHeight (pre-Round rect so round→rect restores after reload); TASK 57: the geometry setters (X/Y/Width/Height) are virtual so a derived element can CONSTRAIN every write (the webcam clamps itself into the vertical tier's band) instead of every writer re-implementing the rule; ClipShape + ToggleClipShape() are virtual too, so a derived element can CONSTRAIN the shape (the Chat scene's vertical camera is rect-only); TASK 59: IsRectShape/IsRoundShape — the shape as a CHOICE (the properties panel shows Rect
VerticalCameraLayout.cs TASK 57 (the "vv" feature): the vertical (9:16) tier's camera rules as pure math — TileWidth/TileHeight (270×152 master px = 480×270 in the 1080×1920 output), Inset (32 master px from the band's outer edge), IsVerticalTier(QualityOption) (portrait tier), AreaFor(band, bottom) (the band splits into two 607×540 areas), MaxSizeFor(band), SpotFor(band, w, h, centreX, centreY) (the six spots — the area and column the tile's centre falls in, inset, never outside the band) and DefaultSpot (bottom-right, the corner the 16:9 default webcam uses), FillsArea(band, width) (the camera is wide enough to fill a whole area = "enlarged") and SizeFor(band, requestedWidth) (the Chat camera's TWO sizes - the small tile or one whole 607×540 area — whichever is nearer the requested width, so the resize handle has two detents)
ZoomSceneElement.cs Transient zoom box (TASK 52, creator-corrected 2026-10-08): carries the box rect AND the anchored CaptureX/CaptureY (the fixed box/2 capture window set on ActivateZoom; moving the box never touches it). IsZoomActive flips Kind Static→Dynamic (leaves the baked base while active); never persisted (LayoutStore save skips non-Source/non-WebcamSceneConfig rows), never shown in the layers list or the element template (IsZoomLayer gates both). The compositor SKIPS the active element in every layer loop and draws its 2x content LAST (layer n+1) via ZoomMagnifier.
Webcam.cs Singleton webcam identity: Id, DeviceId, Name (one row app-wide)
BackgroundEffect.cs TASK 51: per-webcam background effect enum None / Remove / Blur, carried by WebcamSceneConfig
BorderColorPalette.cs TASK 60: the colours the webcam's border-colour drop-down offers — NamedColor(Hex, Name) + BorderColorPalette.All (the single source of truth; the picker builds its menu from it) and NameOf(hex) (case-insensitive; a colour outside the palette keeps its hex). The creator asked for a colour NAME next to each hex: #e94560 Crimson
WebcamSceneConfig.cs Per-scene webcam placement (subclass of SceneElement): geometry + IsVisible + border (BorderColor/BorderOpacity/BorderWidth/BorderAnimation) + VideoImageSource; WebcamId links to Webcam; TASK 51: BackgroundEffect + BackgroundStrength (0..1, default 0.5) + the radio-pill surface RemoveBackground/BlurBackground (one on turns the other off; both off = None) + HasBackgroundEffect (shows the strength slider); TASK 57 (the "vv" feature): the vertical (9:16) tier's OWN placement per scene — VerticalX/Y/Width/Height/VerticalClipShape/VerticalRectWidth/VerticalRectHeight (persisted, NULL = no vertical placement yet) + the transient VerticalBand/VerticalLayoutLive/LandscapeX…LandscapeRectHeight (the parked 16:9 layout) + BeginVerticalLayout/EndVerticalLayout/CommitLiveLayoutToVertical (the tier swap) and the X/Y/Width/Height overrides that clamp every write into the band; VerticalShapeLocked (the Chat scene's vertical layout is rect-only) overrides ClipShape + ToggleClipShape() so no writer can slip a circle in
QualityOption.cs Resolution tier record (Display, Fps, Bitrate, Width, Height); Label formats as 1080p60 (8Mbps) — drives the bottom-bar dropdown and the output-rect math
StreamConfig.cs StreamConfig (note: TargetBitrate/Resolution defaults are stale — not yet wired to the dropdown), StreamHealth (bitrate/FPS/dropped/duration), StreamStatus enum
MicStatus.cs Footer mic indicator: NotConnected / Connected / Problem — the state behind the MIC button's status dot (red = no device/capture off, green = capturing, yellow = a requested mic failed: in use/unplugged)
YouTube.cs YouTubeChannel and ChatMessage (chat feed) — since TASK 43 every message carries Kind (ChatEventKind None/SuperChat/SuperSticker/NewMember/MemberGift/GiftReceived/MemberMilestone) + event payload fields (SuperChatDisplayString, SuperStickerDescription, GiftNewMembersCount, GifterName, MilestoneMonths)
Socials.cs Social bar (global layer, never a Source): SocialService enum (YouTube/Twitch/X/Instagram/TikTok/Facebook/Discord/Kick/Threads/Bluesky/GitHub/LinkedIn/Pinterest/Snapchat/Reddit/WhatsApp/Telegram/Link/Website/Fediverse), SocialEntry (Service/Handle/ProfileUrl/FediverseSoftware), SocialsConfig (Entries + BarPosition Top/Bottom + BarEnabled on/off — BarJustify dropped, column back-compat), SocialServiceIcons (canonical URL builder + DetectService (URL domain / fediverse @user@domain → Fediverse / bare→Website) + bundled SVG logo path data per service (LogoDataFor) + LogoDataForFediverse(software) mapping nodeinfo software names (mastodon/peertube/pixelfed/misskey/lemmy/pleroma/firefish) to logos with a generic fediverse glyph fallback (FediverseIconData) + LockedIconData/DoNotIconData — initials/colors gone)

Related: ViewModels/index.md consume these; Services/LayoutStore.cs persists Scene/Source.