use iced::Rectangle;
use scrive_core::DisplayRow;
pub(crate) const TEXT_PAD: f32 = 6.0;
pub(crate) const CHIP_PILL_RADIUS: f32 = 3.0;
#[derive(Copy, Clone, Debug, PartialEq)]
pub(crate) struct ScrollAnchor {
pub(crate) row: u32,
pub(crate) offset_px: f32,
}
impl ScrollAnchor {
pub(crate) const TOP: Self = Self { row: 0, offset_px: 0.0 };
pub(crate) fn rows(self, line_h: f32) -> f64 {
f64::from(self.row) + f64::from(self.offset_px) / f64::from(line_h)
}
pub(crate) fn from_rows(rows: f64, line_h: f32) -> Self {
let rows = rows.max(0.0);
let row = rows.floor().min(f64::from(u32::MAX)) as u32;
Self { row, offset_px: ((rows - f64::from(row)) * f64::from(line_h)) as f32 }
}
}
#[derive(Copy, Clone, Debug)]
pub(crate) struct Geo {
bounds: Rectangle,
gutter: f32,
advance: f32,
line_h: f32,
scroll_x: f32,
scroll_rows: f64,
}
impl Geo {
pub(crate) fn new(bounds: Rectangle, gutter: f32, advance: f32, line_h: f32, scroll_x: f32, scroll: ScrollAnchor) -> Self {
Self { bounds, gutter, advance, line_h, scroll_x, scroll_rows: scroll.rows(line_h) }
}
pub(crate) fn cell_x(&self, cell: f32) -> f32 {
self.bounds.x + self.gutter + TEXT_PAD + cell * self.advance - self.scroll_x
}
pub(crate) fn x_cell(&self, x: f32) -> f32 {
(x - self.bounds.x - self.gutter - TEXT_PAD + self.scroll_x) / self.advance
}
pub(crate) fn text_left(&self) -> f32 {
self.bounds.x + self.gutter + TEXT_PAD
}
pub(crate) fn row_y(&self, row: DisplayRow) -> f32 {
(f64::from(self.bounds.y)
+ (f64::from(row.index()) - self.scroll_rows) * f64::from(self.line_h)) as f32
}
pub(crate) fn rows_from_top(&self, y: f32) -> f64 {
self.scroll_rows + f64::from(y - self.bounds.y) / f64::from(self.line_h)
}
pub(crate) fn code_left(&self) -> f32 {
self.bounds.x + self.gutter
}
pub(crate) fn in_gutter(&self, x: f32) -> bool {
x < self.code_left()
}
pub(crate) fn bounds(&self) -> Rectangle {
self.bounds
}
pub(crate) fn gutter(&self) -> f32 {
self.gutter
}
pub(crate) fn advance(&self) -> f32 {
self.advance
}
pub(crate) fn line_h(&self) -> f32 {
self.line_h
}
pub(crate) fn chip_pill(&self, center_x: f32, row_top: f32) -> Rectangle {
Rectangle {
x: center_x - self.advance * 1.2,
y: row_top + 2.0,
width: self.advance * 2.4,
height: self.line_h - 4.0,
}
}
pub(crate) fn inline_halo(&self, x0: f32, x1: f32, row_top: f32) -> Rectangle {
Rectangle {
x: x0 - 2.0,
y: row_top + 1.0,
width: (x1 - x0) + self.advance + 4.0,
height: self.line_h - 2.0,
}
}
}