feat(context): Títulos integrados con color adaptativo
Z-Design V5 - Títulos Adaptativos: - derivePanelFrameColors: title_color según luminosidad del fondo - Fondo oscuro (L < 0.5) → base.lightenHsl(90) (blanco teñido) - Fondo claro → base.darkenHsl(90) (negro teñido) - drawPanelFrame: siempre usa title_color (no border_unfocus) - Márgenes título mejorados: x+10, y+5 Resultado: máximo contraste y legibilidad en todos los paneles. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
parent
203a1e6ee5
commit
f7e1e346be
2 changed files with 22 additions and 6 deletions
|
|
@ -657,11 +657,12 @@ pub const Context = struct {
|
||||||
break :blk config.border_color;
|
break :blk config.border_color;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Título adaptativo: siempre alta legibilidad (blanco teñido sobre fondo oscuro)
|
||||||
const title_color: ?Style.Color = blk: {
|
const title_color: ?Style.Color = blk: {
|
||||||
if (config.title_color) |tc| break :blk tc;
|
if (config.title_color) |tc| break :blk tc;
|
||||||
if (config.base_color) |base| {
|
if (config.base_color) |base| {
|
||||||
const derived = Style.derivePanelFrameColors(base);
|
const derived = Style.derivePanelFrameColors(base);
|
||||||
break :blk if (config.has_focus) derived.title_color else derived.border_unfocus;
|
break :blk derived.title_color; // Siempre legible, focus o no
|
||||||
}
|
}
|
||||||
break :blk border_color;
|
break :blk border_color;
|
||||||
};
|
};
|
||||||
|
|
@ -698,12 +699,12 @@ pub const Context = struct {
|
||||||
self.pushCommand(Command.rectOutline(rect.x, rect.y, rect.w, rect.h, border));
|
self.pushCommand(Command.rectOutline(rect.x, rect.y, rect.w, rect.h, border));
|
||||||
}
|
}
|
||||||
|
|
||||||
// 5. Draw title if specified
|
// 5. Draw title if specified (margen 10,5 para aire visual)
|
||||||
if (config.title) |title| {
|
if (config.title) |title| {
|
||||||
if (title_color) |tc| {
|
if (title_color) |tc| {
|
||||||
self.pushCommand(.{ .text = .{
|
self.pushCommand(.{ .text = .{
|
||||||
.x = rect.x + 8,
|
.x = rect.x + 10,
|
||||||
.y = rect.y + 4,
|
.y = rect.y + 5,
|
||||||
.text = title,
|
.text = title,
|
||||||
.color = tc,
|
.color = tc,
|
||||||
} });
|
} });
|
||||||
|
|
|
||||||
|
|
@ -1369,18 +1369,33 @@ pub const DerivedPanelColors = struct {
|
||||||
/// - Fondo con focus: 20% base / 80% negro
|
/// - Fondo con focus: 20% base / 80% negro
|
||||||
/// - Fondo sin focus: 12% base / 88% negro
|
/// - Fondo sin focus: 12% base / 88% negro
|
||||||
///
|
///
|
||||||
|
/// Títulos Adaptativos (2025-12-31):
|
||||||
|
/// - El title_color se calcula para máximo contraste
|
||||||
|
/// - Fondo oscuro → blanco teñido (lightenHsl 90)
|
||||||
|
/// - Fondo claro → negro teñido (darkenHsl 90)
|
||||||
|
///
|
||||||
/// Los widgets usan bg_transition.current DIRECTAMENTE (mismo fondo que panel)
|
/// Los widgets usan bg_transition.current DIRECTAMENTE (mismo fondo que panel)
|
||||||
/// con bisel de 1px para verse como "huecos" o "relieves" integrados.
|
/// con bisel de 1px para verse como "huecos" o "relieves" integrados.
|
||||||
pub fn derivePanelFrameColors(base: Color) DerivedPanelColors {
|
pub fn derivePanelFrameColors(base: Color) DerivedPanelColors {
|
||||||
const black = Color.soft_black;
|
const black = Color.soft_black;
|
||||||
|
|
||||||
// Blend fijo: 20% color con focus, 12% sin focus
|
// Blend fijo: 20% color con focus, 12% sin focus
|
||||||
|
const focus_bg = base.blendTowards(black, 80); // 20% color
|
||||||
|
|
||||||
|
// Título adaptativo: contraste máximo según luminosidad del fondo
|
||||||
|
// Fondos oscuros (L < 0.5) → blanco teñido, claros → negro teñido
|
||||||
|
const bg_luminance = focus_bg.perceptualLuminance();
|
||||||
|
const title_color = if (bg_luminance < 0.5)
|
||||||
|
base.lightenHsl(90) // Blanco teñido (mantiene tono del panel)
|
||||||
|
else
|
||||||
|
base.darkenHsl(90); // Negro teñido
|
||||||
|
|
||||||
return .{
|
return .{
|
||||||
.focus_bg = base.blendTowards(black, 80), // 20% color
|
.focus_bg = focus_bg,
|
||||||
.unfocus_bg = base.blendTowards(black, 88), // 12% color
|
.unfocus_bg = base.blendTowards(black, 88), // 12% color
|
||||||
.border_focus = base,
|
.border_focus = base,
|
||||||
.border_unfocus = base.darken(30),
|
.border_unfocus = base.darken(30),
|
||||||
.title_color = base.lightenHsl(20),
|
.title_color = title_color,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue