Skip to content

Commit

Permalink
feat(Rect): poc Offset struct
Browse files Browse the repository at this point in the history
This is a Proof-of-Concept for an `Offset` struct related to `Rect` manipulation
  • Loading branch information
Valentin271 committed Sep 24, 2023
1 parent 357dc4c commit 898769c
Show file tree
Hide file tree
Showing 3 changed files with 57 additions and 23 deletions.
4 changes: 2 additions & 2 deletions examples/calendar.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ use crossterm::{
execute,
terminal::{disable_raw_mode, enable_raw_mode, EnterAlternateScreen, LeaveAlternateScreen},
};
use ratatui::{prelude::*, widgets::calendar::*};
use ratatui::{layout::Offset, prelude::*, widgets::calendar::*};
use time::{Date, Month, OffsetDateTime};

fn main() -> Result<(), Box<dyn Error>> {
Expand Down Expand Up @@ -38,7 +38,7 @@ fn main() -> Result<(), Box<dyn Error>> {
fn draw<B: Backend>(f: &mut Frame<B>) {
let app_area = f.size();

let calarea = app_area.inset(1, 1);
let calarea = app_area.resize(Offset::topleft(1, 1));

let mut start = OffsetDateTime::now_local()
.unwrap()
Expand Down
67 changes: 49 additions & 18 deletions src/layout.rs
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,36 @@ pub enum Alignment {
Right,
}

#[derive(Debug, Default, Clone, Copy)]
pub struct Offset {
pub top: i32,
pub right: i32,
pub bottom: i32,
pub left: i32,
}

impl Offset {
pub fn topleft(top: i32, left: i32) -> Self {
Self {
top,
right: 0,
bottom: 0,
left,
}
}
}

impl From<(i32, i32)> for Offset {
fn from(value: (i32, i32)) -> Self {
Self {
top: value.0,
right: value.1,
bottom: value.0,
left: value.1,
}
}
}

/// A simple rectangle used in the computation of the layout and to give widgets a hint about the
/// area they are supposed to render to.
#[derive(Debug, Default, Clone, Copy, Eq, PartialEq, Hash)]
Expand Down Expand Up @@ -255,26 +285,24 @@ impl Rect {
/// If the given offset overflows the `Rect`'s fields, resulting values will wrapped around.
///
/// ```
/// # use ratatui::prelude::*;
/// let rect = Rect::new(0, 0, 10, 10).inset(-1, 0);
/// # use ratatui::layout::*;
/// let rect = Rect::new(0, 0, 10, 10).resize(Offset {top: 0, right: 0, bottom: 0, left: -1});
/// assert_eq!(rect, Rect::new(u16::MAX, 0, 11, 10));
/// ```
///
/// # See also
///
/// See also [`Rect::offset`] to only move the `Rect`.
pub fn inset<I, J>(self, x: I, y: J) -> Rect
pub fn resize<I>(self, offset: I) -> Rect
where
I: Into<i64>,
J: Into<i64>,
I: Into<Offset>,
{
let x = x.into();
let y = y.into();
let offset: Offset = offset.into();
Rect {
x: (self.x as i64 + x) as u16,
y: (self.y as i64 + y) as u16,
width: (self.width as i64 - x) as u16,
height: (self.height as i64 - y) as u16,
x: (self.x as i32 + offset.left) as u16,
y: (self.y as i32 + offset.top) as u16,
width: (self.width as i32 + offset.right - offset.left) as u16,
height: (self.height as i32 + offset.bottom - offset.top) as u16,
}
}

Expand All @@ -297,17 +325,17 @@ impl Rect {
///
/// # See also
///
/// See also [`Rect::inset`] to modify the inner size.
/// See also [`Rect::resize`] to modify the inner size.
pub fn offset<I, J>(self, x: I, y: J) -> Rect
where
I: Into<i64>,
J: Into<i64>,
I: Into<i32>,
J: Into<i32>,
{
let x = x.into();
let y = y.into();
Rect {
x: (self.x as i64 + x) as u16,
y: (self.y as i64 + y) as u16,
x: (self.x as i32 + x) as u16,
y: (self.y as i32 + y) as u16,
..self
}
}
Expand Down Expand Up @@ -931,8 +959,11 @@ mod tests {
}

#[test]
fn rect_inset() {
assert_eq!(Rect::new(0, 0, 20, 10).inset(5, 2), Rect::new(5, 2, 15, 8));
fn rect_resize() {
assert_eq!(
Rect::new(0, 0, 20, 10).resize(Offset::topleft(2, 5)),
Rect::new(5, 2, 15, 8)
);
}

#[test]
Expand Down
9 changes: 6 additions & 3 deletions src/widgets/barchart.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
#![warn(missing_docs)]
use crate::prelude::*;
use crate::{layout::Offset, prelude::*};

mod bar;
mod bar_group;
Expand Down Expand Up @@ -348,7 +348,7 @@ impl<'a> BarChart<'a> {
let label_x = bars_area.x;
let bars_area = {
let margin = if label_size == 0 { 0 } else { 1 };
bars_area.inset(label_size + margin, 0)
bars_area.resize(Offset::topleft(0, (label_size + margin) as i32))
};

// convert the bar values to ratatui::symbols::bar::Set
Expand Down Expand Up @@ -386,7 +386,10 @@ impl<'a> BarChart<'a> {
}
}

let bar_value_area = bars_area.offset(0, bar_y + (self.bar_width >> 1));
let bar_value_area = Rect {
y: bar_y + (self.bar_width >> 1),
..bars_area
};

// label
if let Some(label) = &bar.label {
Expand Down

0 comments on commit 898769c

Please sign in to comment.