Add blocks as basis for rendering
This commit is contained in:
parent
d7d25a8390
commit
bb4d0fe047
3 changed files with 225 additions and 0 deletions
|
|
@ -1,4 +1,5 @@
|
|||
mod chat;
|
||||
mod chat2;
|
||||
mod euph;
|
||||
mod input;
|
||||
mod rooms;
|
||||
|
|
|
|||
1
src/ui/chat2.rs
Normal file
1
src/ui/chat2.rs
Normal file
|
|
@ -0,0 +1 @@
|
|||
mod blocks;
|
||||
223
src/ui/chat2/blocks.rs
Normal file
223
src/ui/chat2/blocks.rs
Normal file
|
|
@ -0,0 +1,223 @@
|
|||
//! Common rendering logic.
|
||||
|
||||
use std::collections::{vec_deque, VecDeque};
|
||||
|
||||
use toss::widgets::Predrawn;
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
|
||||
pub struct Range<T> {
|
||||
pub top: T,
|
||||
pub bottom: T,
|
||||
}
|
||||
|
||||
impl<T> Range<T> {
|
||||
pub fn new(top: T, bottom: T) -> Self {
|
||||
Self { top, bottom }
|
||||
}
|
||||
}
|
||||
|
||||
impl Range<i32> {
|
||||
pub fn shifted(self, delta: i32) -> Self {
|
||||
Self::new(self.top + delta, self.bottom + delta)
|
||||
}
|
||||
|
||||
pub fn with_top(self, top: i32) -> Self {
|
||||
self.shifted(top - self.top)
|
||||
}
|
||||
|
||||
pub fn with_bottom(self, bottom: i32) -> Self {
|
||||
self.shifted(bottom - self.bottom)
|
||||
}
|
||||
}
|
||||
|
||||
pub struct Block<Id> {
|
||||
id: Id,
|
||||
widget: Predrawn,
|
||||
focus: Range<i32>,
|
||||
can_be_cursor: bool,
|
||||
}
|
||||
|
||||
impl<Id> Block<Id> {
|
||||
pub fn new(id: Id, widget: Predrawn, can_be_cursor: bool) -> Self {
|
||||
let height: i32 = widget.size().height.into();
|
||||
Self {
|
||||
id,
|
||||
widget,
|
||||
focus: Range::new(0, height),
|
||||
can_be_cursor,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn id(&self) -> &Id {
|
||||
&self.id
|
||||
}
|
||||
|
||||
pub fn into_widget(self) -> Predrawn {
|
||||
self.widget
|
||||
}
|
||||
|
||||
fn height(&self) -> i32 {
|
||||
self.widget.size().height.into()
|
||||
}
|
||||
|
||||
pub fn set_focus(&mut self, focus: Range<i32>) {
|
||||
assert!(0 <= focus.top);
|
||||
assert!(focus.top <= focus.bottom);
|
||||
assert!(focus.bottom <= self.height());
|
||||
self.focus = focus;
|
||||
}
|
||||
|
||||
pub fn focus(&self, range: Range<i32>) -> Range<i32> {
|
||||
Range::new(range.top + self.focus.top, range.top + self.focus.bottom)
|
||||
}
|
||||
|
||||
pub fn can_be_cursor(&self) -> bool {
|
||||
self.can_be_cursor
|
||||
}
|
||||
}
|
||||
|
||||
pub struct Blocks<Id> {
|
||||
blocks: VecDeque<Block<Id>>,
|
||||
range: Range<i32>,
|
||||
end: Range<bool>,
|
||||
}
|
||||
|
||||
impl<Id> Blocks<Id> {
|
||||
pub fn new(at: i32) -> Self {
|
||||
Self {
|
||||
blocks: VecDeque::new(),
|
||||
range: Range::new(at, at),
|
||||
end: Range::new(false, false),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn range(&self) -> Range<i32> {
|
||||
self.range
|
||||
}
|
||||
|
||||
pub fn end(&self) -> Range<bool> {
|
||||
self.end
|
||||
}
|
||||
|
||||
pub fn iter(&self) -> Iter<'_, Id> {
|
||||
Iter {
|
||||
iter: self.blocks.iter(),
|
||||
range: self.range,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn into_iter(self) -> IntoIter<Id> {
|
||||
IntoIter {
|
||||
iter: self.blocks.into_iter(),
|
||||
range: self.range,
|
||||
}
|
||||
}
|
||||
|
||||
// TODO Remove index from search result
|
||||
pub fn find_block(&self, id: &Id) -> Option<(Range<i32>, &Block<Id>)>
|
||||
where
|
||||
Id: Eq,
|
||||
{
|
||||
self.iter().find(|(_, block)| block.id == *id)
|
||||
}
|
||||
|
||||
pub fn push_top(&mut self, block: Block<Id>) {
|
||||
assert!(!self.end.top);
|
||||
self.range.top -= block.height();
|
||||
self.blocks.push_front(block);
|
||||
}
|
||||
|
||||
pub fn push_bottom(&mut self, block: Block<Id>) {
|
||||
assert!(!self.end.bottom);
|
||||
self.range.bottom += block.height();
|
||||
self.blocks.push_back(block);
|
||||
}
|
||||
|
||||
pub fn append_top(&mut self, other: Self) {
|
||||
assert!(!self.end.top);
|
||||
assert!(!other.end.bottom);
|
||||
for block in other.blocks.into_iter().rev() {
|
||||
self.push_top(block);
|
||||
}
|
||||
self.end.top = other.end.top;
|
||||
}
|
||||
|
||||
pub fn append_bottom(&mut self, other: Self) {
|
||||
assert!(!self.end.bottom);
|
||||
assert!(!other.end.top);
|
||||
for block in other.blocks {
|
||||
self.push_bottom(block);
|
||||
}
|
||||
self.end.bottom = other.end.bottom;
|
||||
}
|
||||
|
||||
pub fn end_top(&mut self) {
|
||||
self.end.top = true;
|
||||
}
|
||||
|
||||
pub fn end_bottom(&mut self) {
|
||||
self.end.bottom = true;
|
||||
}
|
||||
|
||||
pub fn shift(&mut self, delta: i32) {
|
||||
self.range = self.range.shifted(delta);
|
||||
}
|
||||
|
||||
pub fn set_top(&mut self, top: i32) {
|
||||
self.shift(top - self.range.top);
|
||||
}
|
||||
|
||||
pub fn set_bottom(&mut self, bottom: i32) {
|
||||
self.shift(bottom - self.range.bottom);
|
||||
}
|
||||
}
|
||||
|
||||
pub struct Iter<'a, Id> {
|
||||
iter: vec_deque::Iter<'a, Block<Id>>,
|
||||
range: Range<i32>,
|
||||
}
|
||||
|
||||
impl<'a, Id> Iterator for Iter<'a, Id> {
|
||||
type Item = (Range<i32>, &'a Block<Id>);
|
||||
|
||||
fn next(&mut self) -> Option<Self::Item> {
|
||||
let block = self.iter.next()?;
|
||||
let range = Range::new(self.range.top, self.range.top + block.height());
|
||||
self.range.top = range.bottom;
|
||||
Some((range, block))
|
||||
}
|
||||
}
|
||||
|
||||
impl<Id> DoubleEndedIterator for Iter<'_, Id> {
|
||||
fn next_back(&mut self) -> Option<Self::Item> {
|
||||
let block = self.iter.next_back()?;
|
||||
let range = Range::new(self.range.bottom - block.height(), self.range.bottom);
|
||||
self.range.bottom = range.top;
|
||||
Some((range, block))
|
||||
}
|
||||
}
|
||||
|
||||
pub struct IntoIter<Id> {
|
||||
iter: vec_deque::IntoIter<Block<Id>>,
|
||||
range: Range<i32>,
|
||||
}
|
||||
|
||||
impl<Id> Iterator for IntoIter<Id> {
|
||||
type Item = (Range<i32>, Block<Id>);
|
||||
|
||||
fn next(&mut self) -> Option<Self::Item> {
|
||||
let block = self.iter.next()?;
|
||||
let range = Range::new(self.range.top, self.range.top + block.height());
|
||||
self.range.top = range.bottom;
|
||||
Some((range, block))
|
||||
}
|
||||
}
|
||||
|
||||
impl<Id> DoubleEndedIterator for IntoIter<Id> {
|
||||
fn next_back(&mut self) -> Option<Self::Item> {
|
||||
let block = self.iter.next_back()?;
|
||||
let range = Range::new(self.range.bottom - block.height(), self.range.bottom);
|
||||
self.range.bottom = range.top;
|
||||
Some((range, block))
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue