Fumble around unsuccessfully with cursor movement
This commit is contained in:
parent
0d77b3cf92
commit
a1c714d116
1 changed files with 262 additions and 9 deletions
|
|
@ -3,7 +3,7 @@
|
||||||
use toss::frame::{Frame, Size};
|
use toss::frame::{Frame, Size};
|
||||||
|
|
||||||
use crate::chat::Cursor;
|
use crate::chat::Cursor;
|
||||||
use crate::store::{Msg, MsgStore};
|
use crate::store::{Msg, MsgStore, Tree};
|
||||||
|
|
||||||
use super::blocks::Blocks;
|
use super::blocks::Blocks;
|
||||||
use super::{util, TreeView};
|
use super::{util, TreeView};
|
||||||
|
|
@ -16,14 +16,14 @@ impl<M: Msg> TreeView<M> {
|
||||||
frame: &mut Frame,
|
frame: &mut Frame,
|
||||||
size: Size,
|
size: Size,
|
||||||
old_blocks: &Blocks<M::Id>,
|
old_blocks: &Blocks<M::Id>,
|
||||||
old_cursor_id: &M::Id,
|
old_cursor_id: &Option<M::Id>,
|
||||||
cursor: &mut Cursor<M::Id>,
|
cursor: &mut Cursor<M::Id>,
|
||||||
) {
|
) {
|
||||||
if let Some(block) = old_blocks.find(&cursor.id) {
|
if let Some(block) = old_blocks.find(&cursor.id) {
|
||||||
// The cursor is still visible in the old blocks, so we just need to
|
// The cursor is still visible in the old blocks, so we just need to
|
||||||
// adjust the proportion such that the blocks stay still.
|
// adjust the proportion such that the blocks stay still.
|
||||||
cursor.proportion = util::line_to_proportion(size.height, block.line);
|
cursor.proportion = util::line_to_proportion(size.height, block.line);
|
||||||
} else {
|
} else if let Some(old_cursor_id) = old_cursor_id {
|
||||||
// The cursor is not visible any more. However, we can estimate
|
// The cursor is not visible any more. However, we can estimate
|
||||||
// whether it is above or below the previous cursor position by
|
// whether it is above or below the previous cursor position by
|
||||||
// lexicographically comparing both positions' paths.
|
// lexicographically comparing both positions' paths.
|
||||||
|
|
@ -38,6 +38,10 @@ impl<M: Msg> TreeView<M> {
|
||||||
// bottom of the screen.
|
// bottom of the screen.
|
||||||
cursor.proportion = 1.0;
|
cursor.proportion = 1.0;
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
// We were scrolled all the way to the bottom, so the cursor must
|
||||||
|
// have been offscreen somewhere above.
|
||||||
|
cursor.proportion = 0.0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// The cursor should be visible in its entirety on the screen now. If it
|
// The cursor should be visible in its entirety on the screen now. If it
|
||||||
|
|
@ -65,16 +69,265 @@ impl<M: Msg> TreeView<M> {
|
||||||
// goes for the other direction.
|
// goes for the other direction.
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn move_up() {
|
/// Move to the previous sibling, or don't move if this is not possible.
|
||||||
todo!()
|
///
|
||||||
|
/// Always stays at the same level of indentation.
|
||||||
|
async fn find_prev_sibling<S: MsgStore<M>>(
|
||||||
|
&self,
|
||||||
|
room: &str,
|
||||||
|
store: &S,
|
||||||
|
tree: &mut Tree<M>,
|
||||||
|
id: &mut M::Id,
|
||||||
|
) {
|
||||||
|
if let Some(siblings) = tree.siblings(id) {
|
||||||
|
let prev_sibling = siblings
|
||||||
|
.iter()
|
||||||
|
.zip(siblings.iter().skip(1))
|
||||||
|
.find(|(_, s)| *s == id)
|
||||||
|
.map(|(s, _)| s);
|
||||||
|
if let Some(prev_sibling) = prev_sibling {
|
||||||
|
*id = prev_sibling.clone();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// We're at the root of our tree, so we need to move to the root of
|
||||||
|
// the previous tree.
|
||||||
|
if let Some(prev_tree_id) = store.prev_tree(room, tree.root()).await {
|
||||||
|
*tree = store.tree(room, &prev_tree_id).await;
|
||||||
|
*id = prev_tree_id;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn move_down() {
|
/// Move to the next sibling, or don't move if this is not possible.
|
||||||
todo!()
|
///
|
||||||
|
/// Always stays at the same level of indentation.
|
||||||
|
async fn find_next_sibling<S: MsgStore<M>>(
|
||||||
|
&self,
|
||||||
|
room: &str,
|
||||||
|
store: &S,
|
||||||
|
tree: &mut Tree<M>,
|
||||||
|
id: &mut M::Id,
|
||||||
|
) {
|
||||||
|
if let Some(siblings) = tree.siblings(id) {
|
||||||
|
let next_sibling = siblings
|
||||||
|
.iter()
|
||||||
|
.zip(siblings.iter().skip(1))
|
||||||
|
.find(|(s, _)| *s == id)
|
||||||
|
.map(|(_, s)| s);
|
||||||
|
if let Some(next_sibling) = next_sibling {
|
||||||
|
*id = next_sibling.clone();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// We're at the root of our tree, so we need to move to the root of
|
||||||
|
// the next tree.
|
||||||
|
if let Some(next_tree_id) = store.next_tree(room, tree.root()).await {
|
||||||
|
*tree = store.tree(room, &next_tree_id).await;
|
||||||
|
*id = next_tree_id;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn move_up_sibling() {
|
fn find_innermost_child(tree: &Tree<M>, id: &mut M::Id) {
|
||||||
todo!()
|
while let Some(children) = tree.children(id) {
|
||||||
|
if let Some(child) = children.last() {
|
||||||
|
*id = child.clone()
|
||||||
|
} else {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Move to the previous message, or don't move if this is not possible.
|
||||||
|
async fn find_prev_msg<S: MsgStore<M>>(
|
||||||
|
&self,
|
||||||
|
room: &str,
|
||||||
|
store: &S,
|
||||||
|
tree: &mut Tree<M>,
|
||||||
|
id: &mut M::Id,
|
||||||
|
) {
|
||||||
|
if let Some(siblings) = tree.siblings(id) {
|
||||||
|
let prev_sibling = siblings
|
||||||
|
.iter()
|
||||||
|
.zip(siblings.iter().skip(1))
|
||||||
|
.find(|(_, s)| *s == id)
|
||||||
|
.map(|(s, _)| s);
|
||||||
|
if let Some(prev_sibling) = prev_sibling {
|
||||||
|
*id = prev_sibling.clone();
|
||||||
|
} else {
|
||||||
|
// We need to move up one parent and *not* down again. If there
|
||||||
|
// was no parent, we should be in the `else` case below instead.
|
||||||
|
if let Some(parent) = tree.parent(id) {
|
||||||
|
*id = parent;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// We're at the root of our tree, so we need to move to the root of
|
||||||
|
// the previous tree.
|
||||||
|
if let Some(prev_tree_id) = store.prev_tree(room, tree.root()).await {
|
||||||
|
*tree = store.tree(room, &prev_tree_id).await;
|
||||||
|
*id = prev_tree_id;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Now, we just need to move to the deepest and last child.
|
||||||
|
Self::find_innermost_child(tree, id);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Move to the next message, or don't move if this is not possible.
|
||||||
|
async fn find_next_msg<S: MsgStore<M>>(
|
||||||
|
&self,
|
||||||
|
room: &str,
|
||||||
|
store: &S,
|
||||||
|
tree: &mut Tree<M>,
|
||||||
|
id: &mut M::Id,
|
||||||
|
) {
|
||||||
|
if let Some(children) = tree.children(id) {
|
||||||
|
if let Some(child) = children.first() {
|
||||||
|
*id = child.clone();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if let Some(siblings) = tree.siblings(id) {
|
||||||
|
let prev_sibling = siblings
|
||||||
|
.iter()
|
||||||
|
.zip(siblings.iter().skip(1))
|
||||||
|
.find(|(_, s)| *s == id)
|
||||||
|
.map(|(s, _)| s);
|
||||||
|
if let Some(next_sibling) = prev_sibling {
|
||||||
|
*id = prev_sibling.clone();
|
||||||
|
} else {
|
||||||
|
// We need to move up one parent and *not* down again. If there
|
||||||
|
// was no parent, we should be in the `else` case below instead.
|
||||||
|
if let Some(parent) = tree.msg(id).and_then(|m| m.parent()) {
|
||||||
|
*id = parent;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// We're at the root of our tree, so we need to move to the root of
|
||||||
|
// the previous tree.
|
||||||
|
if let Some(prev_tree_id) = store.prev_tree(room, tree.root()).await {
|
||||||
|
*tree = store.tree(room, &prev_tree_id).await;
|
||||||
|
*id = prev_tree_id;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Now, we just need to move to the deepest and last child.
|
||||||
|
Self::find_innermost_child(tree, id);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn move_up<S: MsgStore<M>>(
|
||||||
|
&mut self,
|
||||||
|
room: &str,
|
||||||
|
store: &S,
|
||||||
|
cursor: &mut Option<Cursor<M::Id>>,
|
||||||
|
frame: &mut Frame,
|
||||||
|
size: Size,
|
||||||
|
) {
|
||||||
|
let old_blocks = self
|
||||||
|
.layout_blocks(room, store, cursor.as_ref(), frame, size)
|
||||||
|
.await;
|
||||||
|
let old_cursor_id = cursor.as_ref().map(|c| c.id.clone());
|
||||||
|
|
||||||
|
if let Some(cursor) = cursor {
|
||||||
|
let mut tree = store.tree(room, &cursor.id).await;
|
||||||
|
self.find_prev_msg(room, store, &mut tree, &mut cursor.id)
|
||||||
|
.await;
|
||||||
|
} else if let Some(last_tree) = store.last_tree(room).await {
|
||||||
|
let tree = store.tree(room, &last_tree).await;
|
||||||
|
let mut id = last_tree;
|
||||||
|
Self::find_innermost_child(&tree, &mut id);
|
||||||
|
*cursor = Some(Cursor {
|
||||||
|
id,
|
||||||
|
proportion: 1.0,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if let Some(cursor) = cursor {
|
||||||
|
self.correct_cursor_offset(
|
||||||
|
room,
|
||||||
|
store,
|
||||||
|
frame,
|
||||||
|
size,
|
||||||
|
&old_blocks,
|
||||||
|
&old_cursor_id,
|
||||||
|
cursor,
|
||||||
|
)
|
||||||
|
.await;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn move_down<S: MsgStore<M>>(
|
||||||
|
&mut self,
|
||||||
|
room: &str,
|
||||||
|
store: &S,
|
||||||
|
cursor: &mut Option<Cursor<M::Id>>,
|
||||||
|
frame: &mut Frame,
|
||||||
|
size: Size,
|
||||||
|
) {
|
||||||
|
let old_blocks = self
|
||||||
|
.layout_blocks(room, store, cursor.as_ref(), frame, size)
|
||||||
|
.await;
|
||||||
|
let old_cursor_id = cursor.as_ref().map(|c| c.id.clone());
|
||||||
|
|
||||||
|
if let Some(cursor) = cursor {
|
||||||
|
let mut tree = store.tree(room, &cursor.id).await;
|
||||||
|
self.find_next_msg(room, store, &mut tree, &mut cursor.id)
|
||||||
|
.await;
|
||||||
|
}
|
||||||
|
|
||||||
|
if let Some(cursor) = cursor {
|
||||||
|
self.correct_cursor_offset(
|
||||||
|
room,
|
||||||
|
store,
|
||||||
|
frame,
|
||||||
|
size,
|
||||||
|
&old_blocks,
|
||||||
|
&old_cursor_id,
|
||||||
|
cursor,
|
||||||
|
)
|
||||||
|
.await;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn move_up_sibling<S: MsgStore<M>>(
|
||||||
|
&mut self,
|
||||||
|
room: &str,
|
||||||
|
store: &S,
|
||||||
|
cursor: &mut Option<Cursor<M::Id>>,
|
||||||
|
frame: &mut Frame,
|
||||||
|
size: Size,
|
||||||
|
) {
|
||||||
|
let old_blocks = self
|
||||||
|
.layout_blocks(room, store, cursor.as_ref(), frame, size)
|
||||||
|
.await;
|
||||||
|
let old_cursor_id = cursor.as_ref().map(|c| c.id.clone());
|
||||||
|
|
||||||
|
if let Some(cursor) = cursor {
|
||||||
|
let mut tree = store.tree(room, &cursor.id).await;
|
||||||
|
self.find_prev_sibling(room, store, &mut tree, &mut cursor.id)
|
||||||
|
.await;
|
||||||
|
} else if let Some(last_tree) = store.last_tree(room).await {
|
||||||
|
*cursor = Some(Cursor {
|
||||||
|
id: last_tree,
|
||||||
|
proportion: 1.0,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if let Some(cursor) = cursor {
|
||||||
|
self.correct_cursor_offset(
|
||||||
|
room,
|
||||||
|
store,
|
||||||
|
frame,
|
||||||
|
size,
|
||||||
|
&old_blocks,
|
||||||
|
&old_cursor_id,
|
||||||
|
cursor,
|
||||||
|
)
|
||||||
|
.await;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn move_down_sibling() {
|
pub async fn move_down_sibling() {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue