use crate::render::Cell;
use crate::style::Color;
use crate::utils::unicode::{char_width, display_width};
impl RenderContext<'_> {
pub fn draw_hline(&mut self, x: u16, y: u16, len: u16, ch: char, fg: Color) {
for i in 0..len {
self.draw_char(x + i, y, ch, fg);
}
}
pub fn draw_vline(&mut self, x: u16, y: u16, len: u16, ch: char, fg: Color) {
for i in 0..len {
self.draw_char(x, y + i, ch, fg);
}
}
pub fn draw_box_rounded(&mut self, x: u16, y: u16, w: u16, h: u16, fg: Color) {
if w < 2 || h < 2 {
return;
}
self.draw_char(x, y, '╭', fg);
self.draw_char(x + w - 1, y, '╮', fg);
self.draw_char(x, y + h - 1, '╰', fg);
self.draw_char(x + w - 1, y + h - 1, '╯', fg);
self.draw_hline(x + 1, y, w - 2, '─', fg);
self.draw_hline(x + 1, y + h - 1, w - 2, '─', fg);
self.draw_vline(x, y + 1, h - 2, '│', fg);
self.draw_vline(x + w - 1, y + 1, h - 2, '│', fg);
}
pub fn draw_box_no_top(&mut self, x: u16, y: u16, w: u16, h: u16, fg: Color) {
if w < 2 || h < 2 {
return;
}
self.draw_char(x, y + h - 1, '╰', fg);
self.draw_char(x + w - 1, y + h - 1, '╯', fg);
self.draw_hline(x + 1, y + h - 1, w - 2, '─', fg);
self.draw_vline(x, y + 1, h - 2, '│', fg);
self.draw_vline(x + w - 1, y + 1, h - 2, '│', fg);
}
pub fn draw_header_line(
&mut self,
x: u16,
y: u16,
width: u16,
parts: &[(&str, Color)],
border_color: Color,
) {
if width < 4 {
return;
}
self.draw_text(x, y, "╭─", border_color);
let mut pos = x + 2;
for (text, color) in parts {
self.draw_text(pos, y, text, *color);
pos += display_width(text) as u16;
}
let end = x + width - 1;
while pos < end {
self.draw_char(pos, y, '─', border_color);
pos += 1;
}
self.draw_char(end, y, '╮', border_color);
}
pub fn draw_box_single(&mut self, x: u16, y: u16, w: u16, h: u16, fg: Color) {
if w < 2 || h < 2 {
return;
}
self.draw_char(x, y, '┌', fg);
self.draw_char(x + w - 1, y, '┐', fg);
self.draw_char(x, y + h - 1, '└', fg);
self.draw_char(x + w - 1, y + h - 1, '┘', fg);
self.draw_hline(x + 1, y, w - 2, '─', fg);
self.draw_hline(x + 1, y + h - 1, w - 2, '─', fg);
self.draw_vline(x, y + 1, h - 2, '│', fg);
self.draw_vline(x + w - 1, y + 1, h - 2, '│', fg);
}
pub fn draw_box_double(&mut self, x: u16, y: u16, w: u16, h: u16, fg: Color) {
if w < 2 || h < 2 {
return;
}
self.draw_char(x, y, '╔', fg);
self.draw_char(x + w - 1, y, '╗', fg);
self.draw_char(x, y + h - 1, '╚', fg);
self.draw_char(x + w - 1, y + h - 1, '╝', fg);
self.draw_hline(x + 1, y, w - 2, '═', fg);
self.draw_hline(x + 1, y + h - 1, w - 2, '═', fg);
self.draw_vline(x, y + 1, h - 2, '║', fg);
self.draw_vline(x + w - 1, y + 1, h - 2, '║', fg);
}
pub fn fill(&mut self, x: u16, y: u16, w: u16, h: u16, ch: char, fg: Color) {
for dy in 0..h {
for dx in 0..w {
self.draw_char(x + dx, y + dy, ch, fg);
}
}
}
pub fn fill_bg(&mut self, x: u16, y: u16, w: u16, h: u16, bg: Color) {
for dy in 0..h {
for dx in 0..w {
let mut cell = Cell::new(' ');
cell.bg = Some(bg);
self.set(x + dx, y + dy, cell);
}
}
}
pub fn fill_row(&mut self, y: u16, width: u16, fg: Option<Color>, bg: Option<Color>) {
for x in 0..width {
let mut cell = Cell::new(' ');
cell.fg = fg;
cell.bg = bg;
self.set(x, y, cell);
}
}
pub fn clear(&mut self, x: u16, y: u16, w: u16, h: u16) {
for dy in 0..h {
for dx in 0..w {
self.set(x + dx, y + dy, Cell::empty());
}
}
}
pub fn draw_box_titled(&mut self, x: u16, y: u16, w: u16, h: u16, title: &str, fg: Color) {
if w < 2 || h < 2 {
return;
}
self.draw_char(x, y, '╭', fg);
self.draw_char(x + w - 1, y, '╮', fg);
self.draw_char(x, y + h - 1, '╰', fg);
self.draw_char(x + w - 1, y + h - 1, '╯', fg);
self.draw_top_border_with_title(x, y, w, title, '─', fg);
self.draw_hline(x + 1, y + h - 1, w - 2, '─', fg);
self.draw_vline(x, y + 1, h - 2, '│', fg);
self.draw_vline(x + w - 1, y + 1, h - 2, '│', fg);
}
pub fn draw_box_titled_single(
&mut self,
x: u16,
y: u16,
w: u16,
h: u16,
title: &str,
fg: Color,
) {
if w < 2 || h < 2 {
return;
}
self.draw_char(x, y, '┌', fg);
self.draw_char(x + w - 1, y, '┐', fg);
self.draw_char(x, y + h - 1, '└', fg);
self.draw_char(x + w - 1, y + h - 1, '┘', fg);
self.draw_top_border_with_title(x, y, w, title, '─', fg);
self.draw_hline(x + 1, y + h - 1, w - 2, '─', fg);
self.draw_vline(x, y + 1, h - 2, '│', fg);
self.draw_vline(x + w - 1, y + 1, h - 2, '│', fg);
}
pub fn draw_box_titled_double(
&mut self,
x: u16,
y: u16,
w: u16,
h: u16,
title: &str,
fg: Color,
) {
if w < 2 || h < 2 {
return;
}
self.draw_char(x, y, '╔', fg);
self.draw_char(x + w - 1, y, '╗', fg);
self.draw_char(x, y + h - 1, '╚', fg);
self.draw_char(x + w - 1, y + h - 1, '╝', fg);
self.draw_top_border_with_title(x, y, w, title, '═', fg);
self.draw_hline(x + 1, y + h - 1, w - 2, '═', fg);
self.draw_vline(x, y + 1, h - 2, '║', fg);
self.draw_vline(x + w - 1, y + 1, h - 2, '║', fg);
}
fn draw_top_border_with_title(
&mut self,
x: u16,
y: u16,
w: u16,
title: &str,
border_char: char,
fg: Color,
) {
let title_start = 2u16;
let border_end = w.saturating_sub(1);
let mut title_chars = title.chars().peekable();
let mut pos = 1u16;
while pos < border_end {
if pos >= title_start {
if let Some(ch) = title_chars.next() {
let ch_width = char_width(ch) as u16;
if ch_width == 0 {
continue;
}
if pos + ch_width > border_end {
break;
}
self.draw_char(x + pos, y, ch, fg);
for i in 1..ch_width {
self.set(x + pos + i, y, Cell::continuation());
}
pos += ch_width;
continue;
}
}
self.draw_char(x + pos, y, border_char, fg);
pos += 1;
}
}
}
use crate::widget::traits::render_context::RenderContext;