🔒 Repository is read-only – file editing is disabled.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106
//! Wspólny kontekst rysowania widgetów: scena + motyw + silnik tekstu.
//!
//! Widgety nie tworzą własnej sceny — rysują do przekazanej [`Scene`]. `PaintCtx`
//! daje im do tego wygodne skróty (pomiar i wyprowadzanie tekstu).
use libluna_core::style::{weight, FontStyle};
use libluna_core::{Color, Point, Theme};
use libluna_render::{Scene, TextEngine, TextRun};
/// Kontekst przekazywany do `paint` widgetów.
pub struct PaintCtx<'a> {
pub scene: &'a mut Scene,
pub theme: &'a Theme,
pub text: &'a TextEngine,
}
impl<'a> PaintCtx<'a> {
pub fn new(scene: &'a mut Scene, theme: &'a Theme, text: &'a TextEngine) -> Self {
Self { scene, theme, text }
}
/// Szerokość napisu w pikselach logicznych.
pub fn measure(&self, s: &str, size: f64, weight: u16) -> f64 {
self.text.measure(s, size, weight).width
}
/// Szerokość napisu dla stylu z motywu.
pub fn measure_style(&self, s: &str, style: FontStyle) -> f64 {
self.measure(s, style.size, style.weight)
}
/// Rysuje napis; `baseline_y` to linia bazowa.
pub fn label(
&mut self,
x: f64,
baseline_y: f64,
s: &str,
size: f64,
weight: u16,
color: Color,
) {
self.scene.text(
TextRun::new(Point::new(x, baseline_y), s, size)
.with_weight(weight)
.with_color(color),
);
}
/// Napis wyrównany do lewej, wyśrodkowany pionowo w `cy`.
pub fn label_left(&mut self, x: f64, cy: f64, s: &str, size: f64, weight: u16, color: Color) {
self.label(x, cy + size * 0.35, s, size, weight, color);
}
/// Napis wyśrodkowany poziomo w `cx` i pionowo w `cy`.
pub fn label_center(
&mut self,
cx: f64,
cy: f64,
s: &str,
size: f64,
weight: u16,
color: Color,
) {
let w = self.measure(s, size, weight);
self.label(cx - w / 2.0, cy + size * 0.35, s, size, weight, color);
}
/// Napis wyrównany do prawej (koniec w `right_x`), wyśrodkowany w `cy`.
pub fn label_right(
&mut self,
right_x: f64,
cy: f64,
s: &str,
size: f64,
weight: u16,
color: Color,
) {
let w = self.measure(s, size, weight);
self.label_left(right_x - w, cy, s, size, weight, color);
}
/// Domyślny kolor tekstu motywu.
pub fn text_color(&self) -> Color {
self.theme.colors.text
}
/// Kolor akcentu motywu.
pub fn accent(&self) -> Color {
self.theme.colors.accent
}
/// Kolor tekstu drugorzędnego.
pub fn dim_text(&self) -> Color {
self.theme.colors.dim_text
}
/// Domyślny styl tekstu treści.
pub fn body(&self) -> FontStyle {
self.theme.typography.body
}
/// Domyślna grubość „aktywna”.
pub fn medium_weight(&self) -> u16 {
weight::MEDIUM
}
}