Add Float widget
This commit is contained in:
parent
805d1a5e63
commit
38f8c0ed66
2 changed files with 66 additions and 0 deletions
|
|
@ -5,6 +5,7 @@
|
||||||
pub mod background;
|
pub mod background;
|
||||||
pub mod border;
|
pub mod border;
|
||||||
pub mod empty;
|
pub mod empty;
|
||||||
|
pub mod float;
|
||||||
pub mod join;
|
pub mod join;
|
||||||
pub mod layer;
|
pub mod layer;
|
||||||
pub mod list;
|
pub mod list;
|
||||||
|
|
|
||||||
65
src/ui/widgets/float.rs
Normal file
65
src/ui/widgets/float.rs
Normal file
|
|
@ -0,0 +1,65 @@
|
||||||
|
use async_trait::async_trait;
|
||||||
|
use toss::frame::{Frame, Pos, Size};
|
||||||
|
|
||||||
|
use super::{BoxedWidget, Widget};
|
||||||
|
|
||||||
|
pub struct Float {
|
||||||
|
inner: BoxedWidget,
|
||||||
|
horizontal: Option<f32>,
|
||||||
|
vertical: Option<f32>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Float {
|
||||||
|
pub fn new<W: Into<BoxedWidget>>(inner: W) -> Self {
|
||||||
|
Self {
|
||||||
|
inner: inner.into(),
|
||||||
|
horizontal: None,
|
||||||
|
vertical: None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn horizontal(mut self, position: f32) -> Self {
|
||||||
|
self.horizontal = Some(position);
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn vertical(mut self, position: f32) -> Self {
|
||||||
|
self.vertical = Some(position);
|
||||||
|
self
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[async_trait]
|
||||||
|
impl Widget for Float {
|
||||||
|
fn size(&self, frame: &mut Frame, max_width: Option<u16>, max_height: Option<u16>) -> Size {
|
||||||
|
self.inner.size(frame, max_width, max_height)
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn render(self: Box<Self>, frame: &mut Frame) {
|
||||||
|
let size = frame.size();
|
||||||
|
|
||||||
|
let mut inner_size = self.inner.size(frame, Some(size.width), Some(size.height));
|
||||||
|
inner_size.width = inner_size.width.min(size.width);
|
||||||
|
inner_size.height = inner_size.height.min(size.height);
|
||||||
|
|
||||||
|
let mut inner_pos = Pos::ZERO;
|
||||||
|
|
||||||
|
if let Some(horizontal) = self.horizontal {
|
||||||
|
let available = (size.width - inner_size.width) as f32;
|
||||||
|
// Biased towards the left if horizontal lands exactly on the
|
||||||
|
// boundary between two cells
|
||||||
|
inner_pos.x = (horizontal * available as f32).floor().min(available) as i32;
|
||||||
|
}
|
||||||
|
|
||||||
|
if let Some(vertical) = self.vertical {
|
||||||
|
let available = (size.height - inner_size.height) as f32;
|
||||||
|
// Biased towards the top if vertical lands exactly on the boundary
|
||||||
|
// between two cells
|
||||||
|
inner_pos.y = (vertical * available as f32).floor().min(available) as i32;
|
||||||
|
}
|
||||||
|
|
||||||
|
frame.push(inner_pos, inner_size);
|
||||||
|
self.inner.render(frame).await;
|
||||||
|
frame.pop();
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue