Polish window frames: inset title chip, ✕ close button, drop shadow
- Title rendered as a chip inset in the border (┤ titel ├), accent colored when focused, dimmed when not - Close button restyled to ┤✕├ matching the frame - Subtle drop shadow below/right of windows (darkened cells, content underneath stays visible; skipped when a background image is active) Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -216,6 +216,12 @@ fn render_window(
|
||||
WindowContent::PopupDialog { .. } => " TUI-WM ".to_string(),
|
||||
};
|
||||
|
||||
// Diskret skugga nedanför/till höger om fönstret (inte när en
|
||||
// bakgrundsbild används — då ska skrivbordet synas igenom).
|
||||
if outer_bg != Color::Reset {
|
||||
render_shadow(frame, full_rect);
|
||||
}
|
||||
|
||||
frame.render_widget(Clear, full_rect);
|
||||
// Ramzonen målas i skrivbordets färg — annars fylls även hörncellerna
|
||||
// utanför de rundade hörnen med fönstrets bakgrund och rutan ser
|
||||
@@ -233,16 +239,22 @@ fn render_window(
|
||||
Block::default().style(Style::default().bg(content_bg)),
|
||||
inner_rect,
|
||||
);
|
||||
// Titeln renderas som ett "chip" infällt i ramen: ┤ titel ├
|
||||
let title_line = Line::from(vec![
|
||||
Span::styled("┤", border_style),
|
||||
Span::styled(title_text.clone(), theme::window_title(is_focused)),
|
||||
Span::styled("├", border_style),
|
||||
]);
|
||||
frame.render_widget(
|
||||
Block::default()
|
||||
.title(Span::styled(&title_text, theme::window_title()))
|
||||
.title(title_line)
|
||||
.borders(Borders::ALL)
|
||||
.border_type(BorderType::Rounded)
|
||||
.border_style(border_style),
|
||||
full_rect,
|
||||
);
|
||||
|
||||
// Stäng-knapp [X]
|
||||
// Stäng-knapp: ┤✕├ infälld i ramen (✕ U+2715 är ett smalt textglyf)
|
||||
let cb = window.close_btn_rect();
|
||||
if cb.x + 3 <= full_rect.x + full_rect.width {
|
||||
let close_hov = hovered_close == Some(window.id);
|
||||
@@ -251,7 +263,12 @@ fn render_window(
|
||||
} else {
|
||||
Style::default().fg(theme::DANGER)
|
||||
};
|
||||
frame.render_widget(Paragraph::new(Span::styled("[X]", close_style)), cb);
|
||||
let close_line = Line::from(vec![
|
||||
Span::styled("┤", border_style),
|
||||
Span::styled("✕", close_style),
|
||||
Span::styled("├", border_style),
|
||||
]);
|
||||
frame.render_widget(Paragraph::new(close_line), cb);
|
||||
}
|
||||
|
||||
// Resize-hints – bara om fönstret är resizable
|
||||
@@ -309,6 +326,31 @@ fn render_window(
|
||||
}
|
||||
}
|
||||
|
||||
/// Ritar en skugga: raden under och kolumnen till höger om fönstret får
|
||||
/// mörkare bakgrund + dämpad text, så fönstren ser ut att sväva över
|
||||
/// skrivbordet. Muterar cellerna direkt så att underliggande innehåll
|
||||
/// (andra fönster/skrivbordet) syns kvar — bara mörkare.
|
||||
fn render_shadow(frame: &mut Frame, rect: Rect) {
|
||||
let area = frame.area();
|
||||
let buf = frame.buffer_mut();
|
||||
let mut shade = |x: u16, y: u16| {
|
||||
if x < area.width && y < area.height {
|
||||
if let Some(cell) = buf.cell_mut((x, y)) {
|
||||
cell.set_bg(theme::SHADOW_BG);
|
||||
cell.modifier.insert(Modifier::DIM);
|
||||
}
|
||||
}
|
||||
};
|
||||
// Rad under fönstret (förskjuten ett steg åt höger)
|
||||
for x in (rect.x + 1)..(rect.x + rect.width + 1) {
|
||||
shade(x, rect.y + rect.height);
|
||||
}
|
||||
// Kolumn till höger om fönstret
|
||||
for y in (rect.y + 1)..(rect.y + rect.height) {
|
||||
shade(rect.x + rect.width, y);
|
||||
}
|
||||
}
|
||||
|
||||
fn render_popup_dialog(
|
||||
frame: &mut Frame,
|
||||
window: &FloatingWindow,
|
||||
|
||||
13
src/theme.rs
13
src/theme.rs
@@ -64,7 +64,14 @@ pub fn panel_item() -> Style {
|
||||
Style::default().fg(PANEL_TEXT).bg(PANEL_BG)
|
||||
}
|
||||
|
||||
/// Fönstertitel.
|
||||
pub fn window_title() -> Style {
|
||||
Style::default().fg(TEXT).add_modifier(Modifier::BOLD)
|
||||
/// Fönstertitel — accentfärgad när fönstret har fokus.
|
||||
pub fn window_title(focused: bool) -> Style {
|
||||
if focused {
|
||||
Style::default().fg(ACCENT).add_modifier(Modifier::BOLD)
|
||||
} else {
|
||||
Style::default().fg(HINT)
|
||||
}
|
||||
}
|
||||
|
||||
/// Bakgrundsfärg för fönsterskuggan (mörkare än skrivbordet).
|
||||
pub const SHADOW_BG: Color = Color::Indexed(233);
|
||||
|
||||
Reference in New Issue
Block a user