refactor: split every monolithic module into focused submodules
Each source file that had grown beyond a single concern is replaced by an identically-named directory containing focused submodules. `src/event_loop/mod.rs` (878 lines) becomes a directory with clipboard, context_menu, cursor_shape, drag, focus, handlers, invalidation, overlays_reconcile, repeat, run, surface, text_editing, and tooltip. Every widget, input handler, and theme component follows the same split. Public interfaces are unchanged — only the internal file layout moves. image bumped from 0.25.2 to 0.25.9.
This commit is contained in:
@@ -0,0 +1,122 @@
|
||||
// SPDX-License-Identifier: LGPL-2.1-only
|
||||
// Copyright (C) 2026 Liberux Labs, S. L. <info@liberux.net>
|
||||
|
||||
//! The eight-slot semantic [`Palette`] every widget speaks in terms of, plus
|
||||
//! the derived [`WindowControlsSpec`] fallback used when a theme document
|
||||
//! omits the explicit `window_controls` block.
|
||||
|
||||
use crate::types::Color;
|
||||
|
||||
use super::prefs::WindowControlsSpec;
|
||||
use super::slots::SlotStore;
|
||||
|
||||
// ─── Palette ─────────────────────────────────────────────────────────────────
|
||||
|
||||
/// Semantic colour tokens shared by every widget.
|
||||
#[ derive( Debug, Clone, Copy ) ]
|
||||
pub struct Palette
|
||||
{
|
||||
/// Page / wallpaper background when no image is present.
|
||||
pub bg: Color,
|
||||
/// Floating surface over the wallpaper (cards, panels, dock) — usually translucent.
|
||||
pub surface: Color,
|
||||
/// Elevated surface (hovered card, pressed toggle, inner pill).
|
||||
pub surface_alt: Color,
|
||||
/// Primary foreground text.
|
||||
pub text_primary: Color,
|
||||
/// Subdued text (date strip, helper text, disabled labels).
|
||||
pub text_secondary: Color,
|
||||
/// Brand accent used for active toggles, sliders, focus rings.
|
||||
pub accent: Color,
|
||||
/// Thin separators and low-contrast borders.
|
||||
pub divider: Color,
|
||||
/// Tint for symbolic icons (wifi / battery / search / etc).
|
||||
pub icon: Color,
|
||||
/// Foreground colour for destructive / error states — text in
|
||||
/// "delete" buttons, error helper rows under invalid inputs,
|
||||
/// the border of an errored pill.
|
||||
pub danger: Color,
|
||||
/// Soft fill behind error states. Pairs with `danger` as
|
||||
/// foreground; light enough that body text remains legible on
|
||||
/// top.
|
||||
pub danger_bg: Color,
|
||||
}
|
||||
|
||||
// ─── Palette projection ──────────────────────────────────────────────────────
|
||||
|
||||
impl Palette
|
||||
{
|
||||
/// Project a [`SlotStore`] onto the eight canonical palette fields.
|
||||
/// Slot ids are the ones declared in the default theme JSON
|
||||
/// (`bg-page`, `surface`, `surface-alt`, `text-primary`,
|
||||
/// `text-secondary`, `accent`, `divider`, `icon`). Missing slots
|
||||
/// fall back to a documented sensible default so downstream widgets
|
||||
/// never see uninitialised colours. Used by [`crate::theme::palette`] and
|
||||
/// [`crate::theme::window_controls`].
|
||||
pub fn from_slots( slots: &SlotStore ) -> Self
|
||||
{
|
||||
Self
|
||||
{
|
||||
bg: slots.color( "bg-page" ).unwrap_or( Color::WHITE ),
|
||||
surface: slots.color( "surface" ).unwrap_or( Color::WHITE ),
|
||||
surface_alt: slots.color( "surface-alt" ).unwrap_or( Color::WHITE ),
|
||||
text_primary: slots.color( "text-primary" ).unwrap_or( Color::BLACK ),
|
||||
text_secondary: slots.color( "text-secondary" ).unwrap_or( Color::rgba( 0.0, 0.0, 0.0, 0.6 ) ),
|
||||
accent: slots.color( "accent" ).unwrap_or( Color::hex( 0x00, 0xCE, 0xB1 ) ),
|
||||
divider: slots.color( "divider" ).unwrap_or( Color::rgba( 0.0, 0.0, 0.0, 0.08 ) ),
|
||||
icon: slots.color( "icon" ).unwrap_or( Color::BLACK ),
|
||||
// Conservative defaults: a rich red for fg, a tinted
|
||||
// pink wash for bg. Themes can override via the
|
||||
// `danger` / `danger-bg` slot ids.
|
||||
danger: slots.color( "danger" ).unwrap_or( Color::hex( 0xA8, 0x00, 0x10 ) ),
|
||||
danger_bg: slots.color( "danger-bg" ).unwrap_or( Color::rgba( 1.0, 0.85, 0.88, 1.0 ) ),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ─── Shared helpers ──────────────────────────────────────────────────────────
|
||||
|
||||
/// Derive a sensible [`WindowControlsSpec`] from a [`Palette`] when the
|
||||
/// theme document omits the `window_controls` block. Also used by the
|
||||
/// JSON loader in `schema.rs` when individual overrides are absent.
|
||||
pub ( crate ) fn default_window_controls( palette: Palette ) -> WindowControlsSpec
|
||||
{
|
||||
WindowControlsSpec
|
||||
{
|
||||
bar_bg: Color { a: 1.0, ..palette.surface },
|
||||
icon: palette.icon,
|
||||
hover_bg: palette.surface_alt,
|
||||
pressed_bg: palette.divider,
|
||||
close_hover_bg: Color::rgba( 0.92, 0.18, 0.18, 0.90 ),
|
||||
close_icon: Color::WHITE,
|
||||
focus_ring: palette.accent,
|
||||
}
|
||||
}
|
||||
|
||||
#[ cfg( test ) ]
|
||||
mod tests
|
||||
{
|
||||
use super::*;
|
||||
use super::super::slots::{ self, Metadata, Slot };
|
||||
|
||||
#[ test ]
|
||||
fn palette_from_slots_uses_canonical_ids()
|
||||
{
|
||||
let mut store = slots::SlotStore::new();
|
||||
store.insert
|
||||
(
|
||||
"bg-page",
|
||||
Slot::Color { value: Color::hex( 0x01, 0x02, 0x03 ), meta: Metadata::default() },
|
||||
);
|
||||
store.insert
|
||||
(
|
||||
"text-primary",
|
||||
Slot::Color { value: Color::hex( 0xF0, 0xF1, 0xF2 ), meta: Metadata::default() },
|
||||
);
|
||||
let p = Palette::from_slots( &store );
|
||||
assert_eq!( p.bg, Color::hex( 0x01, 0x02, 0x03 ) );
|
||||
assert_eq!( p.text_primary, Color::hex( 0xF0, 0xF1, 0xF2 ) );
|
||||
// Missing slots fall back to documented sensible defaults.
|
||||
assert_eq!( p.icon, Color::BLACK );
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user