summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJoscha <joscha@plugh.de>2022-09-25 21:53:36 +0200
committerJoscha <joscha@plugh.de>2022-09-25 22:22:01 +0200
commit75e3a08b58f51bb439ef3481ad7d8efe960161fe (patch)
treee41646f2d644403835a263c7278bd0fdb7b47e0b
parent9c9d9a51bbfa40300a3bf8602875067ca7524e9e (diff)
Display chat cursor only when chat has focus
-rw-r--r--src/ui/chat.rs5
-rw-r--r--src/ui/chat/tree.rs6
-rw-r--r--src/ui/chat/tree/layout.rs116
-rw-r--r--src/ui/euph/nick_list.rs2
4 files changed, 81 insertions, 48 deletions
diff --git a/src/ui/chat.rs b/src/ui/chat.rs
index b43da76..7e7021c 100644
--- a/src/ui/chat.rs
+++ b/src/ui/chat.rs
@@ -66,10 +66,9 @@ impl<M: Msg, S: MsgStore<M>> ChatState<M, S> {
&self.store
}
- pub fn widget(&self, nick: String, focus: bool) -> Chat<M, S> {
- // TODO Handle focus
+ pub fn widget(&self, nick: String, focused: bool) -> Chat<M, S> {
match self.mode {
- Mode::Tree => Chat::Tree(self.tree.widget(nick)),
+ Mode::Tree => Chat::Tree(self.tree.widget(nick, focused)),
}
}
}
diff --git a/src/ui/chat/tree.rs b/src/ui/chat/tree.rs
index 7fdbc5c..91d939f 100644
--- a/src/ui/chat/tree.rs
+++ b/src/ui/chat/tree.rs
@@ -370,10 +370,11 @@ impl<M: Msg, S: MsgStore<M>> TreeViewState<M, S> {
Self(Arc::new(Mutex::new(InnerTreeViewState::new(store))))
}
- pub fn widget(&self, nick: String) -> TreeView<M, S> {
+ pub fn widget(&self, nick: String, focused: bool) -> TreeView<M, S> {
TreeView {
inner: self.0.clone(),
nick,
+ focused,
}
}
@@ -411,6 +412,7 @@ impl<M: Msg, S: MsgStore<M>> TreeViewState<M, S> {
pub struct TreeView<M: Msg, S: MsgStore<M>> {
inner: Arc<Mutex<InnerTreeViewState<M, S>>>,
nick: String,
+ focused: bool,
}
#[async_trait]
@@ -426,7 +428,7 @@ where
async fn render(self: Box<Self>, frame: &mut Frame) {
let mut guard = self.inner.lock().await;
- let blocks = guard.relayout(&self.nick, frame).await;
+ let blocks = guard.relayout(self.nick, self.focused, frame).await;
let size = frame.size();
for block in blocks.into_blocks().blocks {
diff --git a/src/ui/chat/tree/layout.rs b/src/ui/chat/tree/layout.rs
index f3665a0..35ff3b4 100644
--- a/src/ui/chat/tree/layout.rs
+++ b/src/ui/chat/tree/layout.rs
@@ -16,6 +16,11 @@ fn scrolloff(height: i32) -> i32 {
scrolloff.min(SCROLLOFF)
}
+struct Context {
+ nick: String,
+ focused: bool,
+}
+
impl<M: Msg + ChatMsg, S: MsgStore<M>> InnerTreeViewState<M, S> {
async fn cursor_path(&self, cursor: &Cursor<M::Id>) -> Path<M::Id> {
match cursor {
@@ -64,20 +69,30 @@ impl<M: Msg + ChatMsg, S: MsgStore<M>> InnerTreeViewState<M, S> {
.is_some()
}
- fn editor_block(&self, nick: &str, frame: &mut Frame, indent: usize) -> Block<BlockId<M::Id>> {
- let (widget, cursor_row) = widgets::editor::<M>(frame, indent, nick, &self.editor);
+ fn editor_block(
+ &self,
+ context: &Context,
+ frame: &mut Frame,
+ indent: usize,
+ ) -> Block<BlockId<M::Id>> {
+ let (widget, cursor_row) = widgets::editor::<M>(frame, indent, &context.nick, &self.editor);
let cursor_row = cursor_row as i32;
Block::new(frame, BlockId::Cursor, widget).focus(cursor_row..cursor_row + 1)
}
- fn pseudo_block(&self, nick: &str, frame: &mut Frame, indent: usize) -> Block<BlockId<M::Id>> {
- let widget = widgets::pseudo::<M>(indent, nick, &self.editor);
+ fn pseudo_block(
+ &self,
+ context: &Context,
+ frame: &mut Frame,
+ indent: usize,
+ ) -> Block<BlockId<M::Id>> {
+ let widget = widgets::pseudo::<M>(indent, &context.nick, &self.editor);
Block::new(frame, BlockId::Cursor, widget)
}
fn layout_subtree(
&self,
- nick: &str,
+ context: &Context,
frame: &mut Frame,
tree: &Tree<M>,
indent: usize,
@@ -99,7 +114,7 @@ impl<M: Msg + ChatMsg, S: MsgStore<M>> InnerTreeViewState<M, S> {
};
// Main message body
- let highlighted = self.cursor.refers_to(id);
+ let highlighted = context.focused && self.cursor.refers_to(id);
let widget = if let Some(msg) = tree.msg(id) {
widgets::msg(highlighted, indent, msg, folded_info)
} else {
@@ -112,7 +127,7 @@ impl<M: Msg + ChatMsg, S: MsgStore<M>> InnerTreeViewState<M, S> {
if !folded {
if let Some(children) = tree.children(id) {
for child in children {
- self.layout_subtree(nick, frame, tree, indent + 1, child, blocks);
+ self.layout_subtree(context, frame, tree, indent + 1, child, blocks);
}
}
}
@@ -129,26 +144,31 @@ impl<M: Msg + ChatMsg, S: MsgStore<M>> InnerTreeViewState<M, S> {
Cursor::Editor { .. } => {
blocks
.blocks_mut()
- .push_back(self.editor_block(nick, frame, indent + 1))
+ .push_back(self.editor_block(context, frame, indent + 1))
}
Cursor::Pseudo { .. } => {
blocks
.blocks_mut()
- .push_back(self.pseudo_block(nick, frame, indent + 1))
+ .push_back(self.pseudo_block(context, frame, indent + 1))
}
_ => {}
}
}
}
- fn layout_tree(&self, nick: &str, frame: &mut Frame, tree: Tree<M>) -> TreeBlocks<M::Id> {
+ fn layout_tree(
+ &self,
+ context: &Context,
+ frame: &mut Frame,
+ tree: Tree<M>,
+ ) -> TreeBlocks<M::Id> {
let root = Root::Tree(tree.root().clone());
let mut blocks = TreeBlocks::new(root.clone(), root);
- self.layout_subtree(nick, frame, &tree, 0, tree.root(), &mut blocks);
+ self.layout_subtree(context, frame, &tree, 0, tree.root(), &mut blocks);
blocks
}
- fn layout_bottom(&self, nick: &str, frame: &mut Frame) -> TreeBlocks<M::Id> {
+ fn layout_bottom(&self, context: &Context, frame: &mut Frame) -> TreeBlocks<M::Id> {
let mut blocks = TreeBlocks::new(Root::Bottom, Root::Bottom);
// Ghost cursor, for positioning according to last cursor line
@@ -166,17 +186,22 @@ impl<M: Msg + ChatMsg, S: MsgStore<M>> InnerTreeViewState<M, S> {
}
Cursor::Editor { parent: None, .. } => blocks
.blocks_mut()
- .push_back(self.editor_block(nick, frame, 0)),
+ .push_back(self.editor_block(context, frame, 0)),
Cursor::Pseudo { parent: None, .. } => blocks
.blocks_mut()
- .push_back(self.pseudo_block(nick, frame, 0)),
+ .push_back(self.pseudo_block(context, frame, 0)),
_ => {}
}
blocks
}
- async fn expand_to_top(&self, nick: &str, frame: &mut Frame, blocks: &mut TreeBlocks<M::Id>) {
+ async fn expand_to_top(
+ &self,
+ context: &Context,
+ frame: &mut Frame,
+ blocks: &mut TreeBlocks<M::Id>,
+ ) {
let top_line = 0;
while blocks.blocks().top_line > top_line {
@@ -190,13 +215,13 @@ impl<M: Msg + ChatMsg, S: MsgStore<M>> InnerTreeViewState<M, S> {
None => break,
};
let prev_tree = self.store.tree(&prev_root_id).await;
- blocks.prepend(self.layout_tree(nick, frame, prev_tree));
+ blocks.prepend(self.layout_tree(context, frame, prev_tree));
}
}
async fn expand_to_bottom(
&self,
- nick: &str,
+ context: &Context,
frame: &mut Frame,
blocks: &mut TreeBlocks<M::Id>,
) {
@@ -210,46 +235,46 @@ impl<M: Msg + ChatMsg, S: MsgStore<M>> InnerTreeViewState<M, S> {
};
if let Some(next_root_id) = next_root_id {
let next_tree = self.store.tree(&next_root_id).await;
- blocks.append(self.layout_tree(nick, frame, next_tree));
+ blocks.append(self.layout_tree(context, frame, next_tree));
} else {
- blocks.append(self.layout_bottom(nick, frame));
+ blocks.append(self.layout_bottom(context, frame));
}
}
}
async fn fill_screen_and_clamp_scrolling(
&self,
- nick: &str,
+ context: &Context,
frame: &mut Frame,
blocks: &mut TreeBlocks<M::Id>,
) {
let top_line = 0;
let bottom_line = frame.size().height as i32 - 1;
- self.expand_to_top(nick, frame, blocks).await;
+ self.expand_to_top(context, frame, blocks).await;
if blocks.blocks().top_line > top_line {
blocks.blocks_mut().set_top_line(0);
}
- self.expand_to_bottom(nick, frame, blocks).await;
+ self.expand_to_bottom(context, frame, blocks).await;
if blocks.blocks().bottom_line < bottom_line {
blocks.blocks_mut().set_bottom_line(bottom_line);
}
- self.expand_to_top(nick, frame, blocks).await;
+ self.expand_to_top(context, frame, blocks).await;
}
async fn layout_last_cursor_seed(
&self,
- nick: &str,
+ context: &Context,
frame: &mut Frame,
last_cursor_path: &Path<M::Id>,
) -> TreeBlocks<M::Id> {
match &self.last_cursor {
Cursor::Bottom => {
- let mut blocks = self.layout_bottom(nick, frame);
+ let mut blocks = self.layout_bottom(context, frame);
let bottom_line = frame.size().height as i32 - 1;
blocks.blocks_mut().set_bottom_line(bottom_line);
@@ -257,7 +282,7 @@ impl<M: Msg + ChatMsg, S: MsgStore<M>> InnerTreeViewState<M, S> {
blocks
}
Cursor::Editor { parent: None, .. } | Cursor::Pseudo { parent: None, .. } => {
- let mut blocks = self.layout_bottom(nick, frame);
+ let mut blocks = self.layout_bottom(context, frame);
blocks
.blocks_mut()
@@ -274,7 +299,7 @@ impl<M: Msg + ChatMsg, S: MsgStore<M>> InnerTreeViewState<M, S> {
} => {
let root = last_cursor_path.first();
let tree = self.store.tree(root).await;
- let mut blocks = self.layout_tree(nick, frame, tree);
+ let mut blocks = self.layout_tree(context, frame, tree);
blocks
.blocks_mut()
@@ -287,7 +312,7 @@ impl<M: Msg + ChatMsg, S: MsgStore<M>> InnerTreeViewState<M, S> {
async fn layout_cursor_seed(
&self,
- nick: &str,
+ context: &Context,
frame: &mut Frame,
last_cursor_path: &Path<M::Id>,
cursor_path: &Path<M::Id>,
@@ -298,7 +323,7 @@ impl<M: Msg + ChatMsg, S: MsgStore<M>> InnerTreeViewState<M, S> {
Cursor::Bottom
| Cursor::Editor { parent: None, .. }
| Cursor::Pseudo { parent: None, .. } => {
- let mut blocks = self.layout_bottom(nick, frame);
+ let mut blocks = self.layout_bottom(context, frame);
blocks.blocks_mut().set_bottom_line(bottom_line);
@@ -313,7 +338,7 @@ impl<M: Msg + ChatMsg, S: MsgStore<M>> InnerTreeViewState<M, S> {
} => {
let root = cursor_path.first();
let tree = self.store.tree(root).await;
- let mut blocks = self.layout_tree(nick, frame, tree);
+ let mut blocks = self.layout_tree(context, frame, tree);
let cursor_above_last = cursor_path < last_cursor_path;
let cursor_line = if cursor_above_last { 0 } else { bottom_line };
@@ -328,16 +353,16 @@ impl<M: Msg + ChatMsg, S: MsgStore<M>> InnerTreeViewState<M, S> {
async fn layout_initial_seed(
&self,
- nick: &str,
+ context: &Context,
frame: &mut Frame,
last_cursor_path: &Path<M::Id>,
cursor_path: &Path<M::Id>,
) -> TreeBlocks<M::Id> {
if let Cursor::Bottom = self.cursor {
- self.layout_cursor_seed(nick, frame, last_cursor_path, cursor_path)
+ self.layout_cursor_seed(context, frame, last_cursor_path, cursor_path)
.await
} else {
- self.layout_last_cursor_seed(nick, frame, last_cursor_path)
+ self.layout_last_cursor_seed(context, frame, last_cursor_path)
.await
}
}
@@ -480,7 +505,12 @@ impl<M: Msg + ChatMsg, S: MsgStore<M>> InnerTreeViewState<M, S> {
result
}
- pub async fn relayout(&mut self, nick: &str, frame: &mut Frame) -> TreeBlocks<M::Id> {
+ pub async fn relayout(
+ &mut self,
+ nick: String,
+ focused: bool,
+ frame: &mut Frame,
+ ) -> TreeBlocks<M::Id> {
// The basic idea is this:
//
// First, layout a full screen of blocks around self.last_cursor, using
@@ -499,29 +529,31 @@ impl<M: Msg + ChatMsg, S: MsgStore<M>> InnerTreeViewState<M, S> {
//
// This entire process is complicated by the different kinds of cursors.
+ let context = Context { nick, focused };
+
let last_cursor_path = self.cursor_path(&self.last_cursor).await;
let cursor_path = self.cursor_path(&self.cursor).await;
self.make_path_visible(&cursor_path);
let mut blocks = self
- .layout_initial_seed(nick, frame, &last_cursor_path, &cursor_path)
+ .layout_initial_seed(&context, frame, &last_cursor_path, &cursor_path)
.await;
blocks.blocks_mut().offset(self.scroll);
- self.fill_screen_and_clamp_scrolling(nick, frame, &mut blocks)
+ self.fill_screen_and_clamp_scrolling(&context, frame, &mut blocks)
.await;
if !self.contains_cursor(&blocks) {
blocks = self
- .layout_cursor_seed(nick, frame, &last_cursor_path, &cursor_path)
+ .layout_cursor_seed(&context, frame, &last_cursor_path, &cursor_path)
.await;
- self.fill_screen_and_clamp_scrolling(nick, frame, &mut blocks)
+ self.fill_screen_and_clamp_scrolling(&context, frame, &mut blocks)
.await;
}
match self.correction {
Some(Correction::MakeCursorVisible) => {
self.scroll_so_cursor_is_visible(frame, &mut blocks);
- self.fill_screen_and_clamp_scrolling(nick, frame, &mut blocks)
+ self.fill_screen_and_clamp_scrolling(&context, frame, &mut blocks)
.await;
}
Some(Correction::MoveCursorToVisibleArea) => {
@@ -539,15 +571,15 @@ impl<M: Msg + ChatMsg, S: MsgStore<M>> InnerTreeViewState<M, S> {
let last_cursor_path = self.store.path(&cursor_msg_id).await;
blocks = self
- .layout_last_cursor_seed(nick, frame, &last_cursor_path)
+ .layout_last_cursor_seed(&context, frame, &last_cursor_path)
.await;
- self.fill_screen_and_clamp_scrolling(nick, frame, &mut blocks)
+ self.fill_screen_and_clamp_scrolling(&context, frame, &mut blocks)
.await;
}
}
Some(Correction::CenterCursor) => {
self.scroll_so_cursor_is_centered(frame, &mut blocks);
- self.fill_screen_and_clamp_scrolling(nick, frame, &mut blocks)
+ self.fill_screen_and_clamp_scrolling(&context, frame, &mut blocks)
.await;
}
None => {}
diff --git a/src/ui/euph/nick_list.rs b/src/ui/euph/nick_list.rs
index ae12823..18b9f42 100644
--- a/src/ui/euph/nick_list.rs
+++ b/src/ui/euph/nick_list.rs
@@ -12,7 +12,7 @@ use crate::ui::widgets::list::{List, ListState};
use crate::ui::widgets::text::Text;
use crate::ui::widgets::BoxedWidget;
-pub fn widget(state: &ListState<String>, joined: &Joined, focus: bool) -> BoxedWidget {
+pub fn widget(state: &ListState<String>, joined: &Joined, focused: bool) -> BoxedWidget {
// TODO Handle focus
let mut list = state.widget();
render_rows(&mut list, joined);