listings: fix selection not appearing immediately and invalid motions
parent
2224a7100f
commit
b9030a684c
|
@ -93,9 +93,10 @@ impl<T> RowsState<T> {
|
||||||
&mut self,
|
&mut self,
|
||||||
thread: ThreadHash,
|
thread: ThreadHash,
|
||||||
metadata: T,
|
metadata: T,
|
||||||
env_hashes: SmallVec<[EnvelopeHash; 8]>,
|
mut env_hashes: SmallVec<[EnvelopeHash; 8]>,
|
||||||
entry_strings: EntryStrings,
|
entry_strings: EntryStrings,
|
||||||
) {
|
) {
|
||||||
|
env_hashes.dedup();
|
||||||
let index = self.entries.len();
|
let index = self.entries.len();
|
||||||
self.thread_order.insert(thread, index);
|
self.thread_order.insert(thread, index);
|
||||||
self.all_threads.insert(thread);
|
self.all_threads.insert(thread);
|
||||||
|
|
|
@ -1372,9 +1372,7 @@ impl Component for CompactListing {
|
||||||
if let Some(mvm) = self.movement.as_ref() {
|
if let Some(mvm) = self.movement.as_ref() {
|
||||||
match mvm {
|
match mvm {
|
||||||
PageMovement::Up(amount) => {
|
PageMovement::Up(amount) => {
|
||||||
for c in self.new_cursor_pos.2.saturating_sub(*amount)
|
for c in self.cursor_pos.2.saturating_sub(*amount)..=self.cursor_pos.2 {
|
||||||
..=self.new_cursor_pos.2
|
|
||||||
{
|
|
||||||
if let Some(thread) = self.get_thread_under_cursor(c) {
|
if let Some(thread) = self.get_thread_under_cursor(c) {
|
||||||
self.rows.update_selection_with_thread(
|
self.rows.update_selection_with_thread(
|
||||||
thread,
|
thread,
|
||||||
|
@ -1390,8 +1388,8 @@ impl Component for CompactListing {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if modifier == Modifier::Intersection {
|
if modifier == Modifier::Intersection {
|
||||||
for c in (0..self.new_cursor_pos.2.saturating_sub(*amount))
|
for c in (0..self.cursor_pos.2.saturating_sub(*amount))
|
||||||
.chain((self.new_cursor_pos.2 + 2)..self.length)
|
.chain((self.cursor_pos.2 + 2)..self.length)
|
||||||
{
|
{
|
||||||
if let Some(thread) = self.get_thread_under_cursor(c) {
|
if let Some(thread) = self.get_thread_under_cursor(c) {
|
||||||
self.rows
|
self.rows
|
||||||
|
@ -1401,8 +1399,8 @@ impl Component for CompactListing {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
PageMovement::PageUp(multiplier) => {
|
PageMovement::PageUp(multiplier) => {
|
||||||
for c in self.new_cursor_pos.2.saturating_sub(rows * multiplier)
|
for c in self.cursor_pos.2.saturating_sub(rows * multiplier)
|
||||||
..=self.new_cursor_pos.2
|
..=self.cursor_pos.2
|
||||||
{
|
{
|
||||||
if let Some(thread) = self.get_thread_under_cursor(c) {
|
if let Some(thread) = self.get_thread_under_cursor(c) {
|
||||||
self.rows.update_selection_with_thread(
|
self.rows.update_selection_with_thread(
|
||||||
|
@ -1420,8 +1418,8 @@ impl Component for CompactListing {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
PageMovement::Down(amount) => {
|
PageMovement::Down(amount) => {
|
||||||
for c in self.new_cursor_pos.2
|
for c in self.cursor_pos.2
|
||||||
..std::cmp::min(self.length, self.new_cursor_pos.2 + amount + 1)
|
..std::cmp::min(self.length, self.cursor_pos.2 + amount + 1)
|
||||||
{
|
{
|
||||||
if let Some(thread) = self.get_thread_under_cursor(c) {
|
if let Some(thread) = self.get_thread_under_cursor(c) {
|
||||||
self.rows.update_selection_with_thread(
|
self.rows.update_selection_with_thread(
|
||||||
|
@ -1438,9 +1436,9 @@ impl Component for CompactListing {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if modifier == Modifier::Intersection {
|
if modifier == Modifier::Intersection {
|
||||||
for c in (0..self.new_cursor_pos.2).chain(
|
for c in (0..self.cursor_pos.2).chain(
|
||||||
(std::cmp::min(self.length, self.new_cursor_pos.2 + amount + 1)
|
(std::cmp::min(self.length, self.cursor_pos.2 + amount) + 1)
|
||||||
+ 1)..self.length,
|
..self.length,
|
||||||
) {
|
) {
|
||||||
if let Some(thread) = self.get_thread_under_cursor(c) {
|
if let Some(thread) = self.get_thread_under_cursor(c) {
|
||||||
self.rows
|
self.rows
|
||||||
|
@ -1450,9 +1448,9 @@ impl Component for CompactListing {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
PageMovement::PageDown(multiplier) => {
|
PageMovement::PageDown(multiplier) => {
|
||||||
for c in self.new_cursor_pos.2
|
for c in self.cursor_pos.2
|
||||||
..std::cmp::min(
|
..std::cmp::min(
|
||||||
self.new_cursor_pos.2 + rows * multiplier + 1,
|
self.cursor_pos.2 + rows * multiplier + 1,
|
||||||
self.length,
|
self.length,
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
|
@ -1471,9 +1469,9 @@ impl Component for CompactListing {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if modifier == Modifier::Intersection {
|
if modifier == Modifier::Intersection {
|
||||||
for c in (0..self.new_cursor_pos.2).chain(
|
for c in (0..self.cursor_pos.2).chain(
|
||||||
(std::cmp::min(
|
(std::cmp::min(
|
||||||
self.new_cursor_pos.2 + rows * multiplier + 1,
|
self.cursor_pos.2 + rows * multiplier,
|
||||||
self.length,
|
self.length,
|
||||||
) + 1)..self.length,
|
) + 1)..self.length,
|
||||||
) {
|
) {
|
||||||
|
@ -1486,7 +1484,7 @@ impl Component for CompactListing {
|
||||||
}
|
}
|
||||||
PageMovement::Right(_) | PageMovement::Left(_) => {}
|
PageMovement::Right(_) | PageMovement::Left(_) => {}
|
||||||
PageMovement::Home => {
|
PageMovement::Home => {
|
||||||
for c in 0..=self.new_cursor_pos.2 {
|
for c in 0..=self.cursor_pos.2 {
|
||||||
if let Some(thread) = self.get_thread_under_cursor(c) {
|
if let Some(thread) = self.get_thread_under_cursor(c) {
|
||||||
self.rows.update_selection_with_thread(
|
self.rows.update_selection_with_thread(
|
||||||
thread,
|
thread,
|
||||||
|
@ -1502,7 +1500,7 @@ impl Component for CompactListing {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if modifier == Modifier::Intersection {
|
if modifier == Modifier::Intersection {
|
||||||
for c in (self.new_cursor_pos.2 + 1)..self.length {
|
for c in (self.cursor_pos.2)..self.length {
|
||||||
if let Some(thread) = self.get_thread_under_cursor(c) {
|
if let Some(thread) = self.get_thread_under_cursor(c) {
|
||||||
self.rows
|
self.rows
|
||||||
.update_selection_with_thread(thread, |e| *e = false);
|
.update_selection_with_thread(thread, |e| *e = false);
|
||||||
|
@ -1511,7 +1509,7 @@ impl Component for CompactListing {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
PageMovement::End => {
|
PageMovement::End => {
|
||||||
for c in self.new_cursor_pos.2..self.length {
|
for c in self.cursor_pos.2..self.length {
|
||||||
if let Some(thread) = self.get_thread_under_cursor(c) {
|
if let Some(thread) = self.get_thread_under_cursor(c) {
|
||||||
self.rows.update_selection_with_thread(
|
self.rows.update_selection_with_thread(
|
||||||
thread,
|
thread,
|
||||||
|
@ -1527,7 +1525,7 @@ impl Component for CompactListing {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if modifier == Modifier::Intersection {
|
if modifier == Modifier::Intersection {
|
||||||
for c in 0..self.new_cursor_pos.2 {
|
for c in 0..self.cursor_pos.2 {
|
||||||
if let Some(thread) = self.get_thread_under_cursor(c) {
|
if let Some(thread) = self.get_thread_under_cursor(c) {
|
||||||
self.rows
|
self.rows
|
||||||
.update_selection_with_thread(thread, |e| *e = false);
|
.update_selection_with_thread(thread, |e| *e = false);
|
||||||
|
@ -1547,18 +1545,7 @@ impl Component for CompactListing {
|
||||||
let page_no = (self.new_cursor_pos.2).wrapping_div(rows);
|
let page_no = (self.new_cursor_pos.2).wrapping_div(rows);
|
||||||
|
|
||||||
let top_idx = page_no * rows;
|
let top_idx = page_no * rows;
|
||||||
if row >= top_idx && row < top_idx + rows {
|
self.force_draw |= row >= top_idx && row < top_idx + rows;
|
||||||
let new_area = nth_row_area(area, row % rows);
|
|
||||||
self.data_columns.draw(
|
|
||||||
grid,
|
|
||||||
row,
|
|
||||||
self.cursor_pos.2,
|
|
||||||
grid.bounds_iter(new_area),
|
|
||||||
);
|
|
||||||
let row_attr = self.rows.row_attr_cache[&row];
|
|
||||||
change_colors(grid, new_area, row_attr.fg, row_attr.bg);
|
|
||||||
context.dirty_areas.push_back(new_area);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if self.force_draw {
|
if self.force_draw {
|
||||||
/* Draw the entire list */
|
/* Draw the entire list */
|
||||||
|
@ -1666,6 +1653,7 @@ impl Component for CompactListing {
|
||||||
{
|
{
|
||||||
self.rows
|
self.rows
|
||||||
.update_selection_with_thread(thread_hash, |e| *e = !*e);
|
.update_selection_with_thread(thread_hash, |e| *e = !*e);
|
||||||
|
self.set_dirty(true);
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -473,7 +473,9 @@ impl ListingTrait for ConversationsListing {
|
||||||
self.highlight_line(grid, new_area, *idx, context);
|
self.highlight_line(grid, new_area, *idx, context);
|
||||||
context.dirty_areas.push_back(new_area);
|
context.dirty_areas.push_back(new_area);
|
||||||
}
|
}
|
||||||
return;
|
if !self.force_draw {
|
||||||
|
return;
|
||||||
|
}
|
||||||
} else if self.cursor_pos != self.new_cursor_pos {
|
} else if self.cursor_pos != self.new_cursor_pos {
|
||||||
self.cursor_pos = self.new_cursor_pos;
|
self.cursor_pos = self.new_cursor_pos;
|
||||||
}
|
}
|
||||||
|
@ -1012,9 +1014,7 @@ impl Component for ConversationsListing {
|
||||||
if let Some(mvm) = self.movement.as_ref() {
|
if let Some(mvm) = self.movement.as_ref() {
|
||||||
match mvm {
|
match mvm {
|
||||||
PageMovement::Up(amount) => {
|
PageMovement::Up(amount) => {
|
||||||
for c in self.new_cursor_pos.2.saturating_sub(*amount)
|
for c in self.cursor_pos.2.saturating_sub(*amount)..=self.cursor_pos.2 {
|
||||||
..=self.new_cursor_pos.2
|
|
||||||
{
|
|
||||||
if let Some(thread) = self.get_thread_under_cursor(c) {
|
if let Some(thread) = self.get_thread_under_cursor(c) {
|
||||||
self.rows.update_selection_with_thread(
|
self.rows.update_selection_with_thread(
|
||||||
thread,
|
thread,
|
||||||
|
@ -1030,8 +1030,8 @@ impl Component for ConversationsListing {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if modifier == Modifier::Intersection {
|
if modifier == Modifier::Intersection {
|
||||||
for c in (0..self.new_cursor_pos.2.saturating_sub(*amount))
|
for c in (0..self.cursor_pos.2.saturating_sub(*amount))
|
||||||
.chain((self.new_cursor_pos.2 + 2)..self.length)
|
.chain((self.cursor_pos.2 + 2)..self.length)
|
||||||
{
|
{
|
||||||
if let Some(thread) = self.get_thread_under_cursor(c) {
|
if let Some(thread) = self.get_thread_under_cursor(c) {
|
||||||
self.rows
|
self.rows
|
||||||
|
@ -1041,8 +1041,8 @@ impl Component for ConversationsListing {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
PageMovement::PageUp(multiplier) => {
|
PageMovement::PageUp(multiplier) => {
|
||||||
for c in self.new_cursor_pos.2.saturating_sub(rows * multiplier)
|
for c in self.cursor_pos.2.saturating_sub(rows * multiplier)
|
||||||
..=self.new_cursor_pos.2
|
..=self.cursor_pos.2
|
||||||
{
|
{
|
||||||
if let Some(thread) = self.get_thread_under_cursor(c) {
|
if let Some(thread) = self.get_thread_under_cursor(c) {
|
||||||
self.rows.update_selection_with_thread(
|
self.rows.update_selection_with_thread(
|
||||||
|
@ -1060,8 +1060,8 @@ impl Component for ConversationsListing {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
PageMovement::Down(amount) => {
|
PageMovement::Down(amount) => {
|
||||||
for c in self.new_cursor_pos.2
|
for c in self.cursor_pos.2
|
||||||
..std::cmp::min(self.length, self.new_cursor_pos.2 + amount + 1)
|
..std::cmp::min(self.length, self.cursor_pos.2 + amount + 1)
|
||||||
{
|
{
|
||||||
if let Some(thread) = self.get_thread_under_cursor(c) {
|
if let Some(thread) = self.get_thread_under_cursor(c) {
|
||||||
self.rows.update_selection_with_thread(
|
self.rows.update_selection_with_thread(
|
||||||
|
@ -1078,9 +1078,9 @@ impl Component for ConversationsListing {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if modifier == Modifier::Intersection {
|
if modifier == Modifier::Intersection {
|
||||||
for c in (0..self.new_cursor_pos.2).chain(
|
for c in (0..self.cursor_pos.2).chain(
|
||||||
(std::cmp::min(self.length, self.new_cursor_pos.2 + amount + 1)
|
(std::cmp::min(self.length, self.cursor_pos.2 + amount + 1) + 1)
|
||||||
+ 1)..self.length,
|
..self.length,
|
||||||
) {
|
) {
|
||||||
if let Some(thread) = self.get_thread_under_cursor(c) {
|
if let Some(thread) = self.get_thread_under_cursor(c) {
|
||||||
self.rows
|
self.rows
|
||||||
|
@ -1090,9 +1090,9 @@ impl Component for ConversationsListing {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
PageMovement::PageDown(multiplier) => {
|
PageMovement::PageDown(multiplier) => {
|
||||||
for c in self.new_cursor_pos.2
|
for c in self.cursor_pos.2
|
||||||
..std::cmp::min(
|
..std::cmp::min(
|
||||||
self.new_cursor_pos.2 + rows * multiplier + 1,
|
self.cursor_pos.2 + rows * multiplier + 1,
|
||||||
self.length,
|
self.length,
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
|
@ -1111,9 +1111,9 @@ impl Component for ConversationsListing {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if modifier == Modifier::Intersection {
|
if modifier == Modifier::Intersection {
|
||||||
for c in (0..self.new_cursor_pos.2).chain(
|
for c in (0..self.cursor_pos.2).chain(
|
||||||
(std::cmp::min(
|
(std::cmp::min(
|
||||||
self.new_cursor_pos.2 + rows * multiplier + 1,
|
self.cursor_pos.2 + rows * multiplier + 1,
|
||||||
self.length,
|
self.length,
|
||||||
) + 1)..self.length,
|
) + 1)..self.length,
|
||||||
) {
|
) {
|
||||||
|
@ -1126,7 +1126,7 @@ impl Component for ConversationsListing {
|
||||||
}
|
}
|
||||||
PageMovement::Right(_) | PageMovement::Left(_) => {}
|
PageMovement::Right(_) | PageMovement::Left(_) => {}
|
||||||
PageMovement::Home => {
|
PageMovement::Home => {
|
||||||
for c in 0..=self.new_cursor_pos.2 {
|
for c in 0..=self.cursor_pos.2 {
|
||||||
if let Some(thread) = self.get_thread_under_cursor(c) {
|
if let Some(thread) = self.get_thread_under_cursor(c) {
|
||||||
self.rows.update_selection_with_thread(
|
self.rows.update_selection_with_thread(
|
||||||
thread,
|
thread,
|
||||||
|
@ -1142,7 +1142,7 @@ impl Component for ConversationsListing {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if modifier == Modifier::Intersection {
|
if modifier == Modifier::Intersection {
|
||||||
for c in (self.new_cursor_pos.2 + 1)..self.length {
|
for c in (self.cursor_pos.2 + 1)..self.length {
|
||||||
if let Some(thread) = self.get_thread_under_cursor(c) {
|
if let Some(thread) = self.get_thread_under_cursor(c) {
|
||||||
self.rows
|
self.rows
|
||||||
.update_selection_with_thread(thread, |e| *e = false);
|
.update_selection_with_thread(thread, |e| *e = false);
|
||||||
|
@ -1151,7 +1151,7 @@ impl Component for ConversationsListing {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
PageMovement::End => {
|
PageMovement::End => {
|
||||||
for c in self.new_cursor_pos.2..self.length {
|
for c in self.cursor_pos.2..self.length {
|
||||||
if let Some(thread) = self.get_thread_under_cursor(c) {
|
if let Some(thread) = self.get_thread_under_cursor(c) {
|
||||||
self.rows.update_selection_with_thread(
|
self.rows.update_selection_with_thread(
|
||||||
thread,
|
thread,
|
||||||
|
@ -1167,7 +1167,7 @@ impl Component for ConversationsListing {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if modifier == Modifier::Intersection {
|
if modifier == Modifier::Intersection {
|
||||||
for c in 0..self.new_cursor_pos.2 {
|
for c in 0..self.cursor_pos.2 {
|
||||||
if let Some(thread) = self.get_thread_under_cursor(c) {
|
if let Some(thread) = self.get_thread_under_cursor(c) {
|
||||||
self.rows
|
self.rows
|
||||||
.update_selection_with_thread(thread, |e| *e = false);
|
.update_selection_with_thread(thread, |e| *e = false);
|
||||||
|
@ -1177,7 +1177,9 @@ impl Component for ConversationsListing {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
self.force_draw = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if !self.rows.row_updates.is_empty() {
|
if !self.rows.row_updates.is_empty() {
|
||||||
/* certain rows need to be updated (eg an unseen message was just set seen)
|
/* certain rows need to be updated (eg an unseen message was just set seen)
|
||||||
* */
|
* */
|
||||||
|
@ -1305,6 +1307,7 @@ impl Component for ConversationsListing {
|
||||||
self.modifier_command = Some(Modifier::default());
|
self.modifier_command = Some(Modifier::default());
|
||||||
} else if let Some(thread) = self.get_thread_under_cursor(self.cursor_pos.2) {
|
} else if let Some(thread) = self.get_thread_under_cursor(self.cursor_pos.2) {
|
||||||
self.rows.update_selection_with_thread(thread, |e| *e = !*e);
|
self.rows.update_selection_with_thread(thread, |e| *e = !*e);
|
||||||
|
self.set_dirty(true);
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -461,7 +461,9 @@ impl ListingTrait for PlainListing {
|
||||||
}
|
}
|
||||||
context.dirty_areas.push_back(new_area);
|
context.dirty_areas.push_back(new_area);
|
||||||
}
|
}
|
||||||
return;
|
if !self.force_draw {
|
||||||
|
return;
|
||||||
|
}
|
||||||
} else if self.cursor_pos != self.new_cursor_pos {
|
} else if self.cursor_pos != self.new_cursor_pos {
|
||||||
self.cursor_pos = self.new_cursor_pos;
|
self.cursor_pos = self.new_cursor_pos;
|
||||||
}
|
}
|
||||||
|
@ -1025,37 +1027,194 @@ impl Component for PlainListing {
|
||||||
area = (set_y(upper_left, y + 1), bottom_right);
|
area = (set_y(upper_left, y + 1), bottom_right);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let (upper_left, bottom_right) = area;
|
||||||
|
let rows = get_y(bottom_right) - get_y(upper_left) + 1;
|
||||||
|
|
||||||
|
if let Some(modifier) = self.modifier_command.take() {
|
||||||
|
if let Some(mvm) = self.movement.as_ref() {
|
||||||
|
match mvm {
|
||||||
|
PageMovement::Up(amount) => {
|
||||||
|
for c in self.cursor_pos.2.saturating_sub(*amount)..=self.cursor_pos.2 {
|
||||||
|
if let Some(env_hash) = self.get_env_under_cursor(c) {
|
||||||
|
self.rows.update_selection_with_env(
|
||||||
|
env_hash,
|
||||||
|
match modifier {
|
||||||
|
Modifier::SymmetricDifference => {
|
||||||
|
|e: &mut bool| *e = !*e
|
||||||
|
}
|
||||||
|
Modifier::Union => |e: &mut bool| *e = true,
|
||||||
|
Modifier::Difference => |e: &mut bool| *e = false,
|
||||||
|
Modifier::Intersection => |_: &mut bool| {},
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if modifier == Modifier::Intersection {
|
||||||
|
for c in (0..self.cursor_pos.2.saturating_sub(*amount))
|
||||||
|
.chain((self.cursor_pos.2 + 2)..self.length)
|
||||||
|
{
|
||||||
|
if let Some(env_hash) = self.get_env_under_cursor(c) {
|
||||||
|
self.rows
|
||||||
|
.update_selection_with_env(env_hash, |e| *e = false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
PageMovement::PageUp(multiplier) => {
|
||||||
|
for c in self.cursor_pos.2.saturating_sub(rows * multiplier)
|
||||||
|
..=self.cursor_pos.2
|
||||||
|
{
|
||||||
|
if let Some(env_hash) = self.get_env_under_cursor(c) {
|
||||||
|
self.rows.update_selection_with_env(
|
||||||
|
env_hash,
|
||||||
|
match modifier {
|
||||||
|
Modifier::SymmetricDifference => {
|
||||||
|
|e: &mut bool| *e = !*e
|
||||||
|
}
|
||||||
|
Modifier::Union => |e: &mut bool| *e = true,
|
||||||
|
Modifier::Difference => |e: &mut bool| *e = false,
|
||||||
|
Modifier::Intersection => |_: &mut bool| {},
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
PageMovement::Down(amount) => {
|
||||||
|
for c in self.cursor_pos.2
|
||||||
|
..std::cmp::min(self.length, self.cursor_pos.2 + amount + 1)
|
||||||
|
{
|
||||||
|
if let Some(env_hash) = self.get_env_under_cursor(c) {
|
||||||
|
self.rows.update_selection_with_env(
|
||||||
|
env_hash,
|
||||||
|
match modifier {
|
||||||
|
Modifier::SymmetricDifference => {
|
||||||
|
|e: &mut bool| *e = !*e
|
||||||
|
}
|
||||||
|
Modifier::Union => |e: &mut bool| *e = true,
|
||||||
|
Modifier::Difference => |e: &mut bool| *e = false,
|
||||||
|
Modifier::Intersection => |_: &mut bool| {},
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if modifier == Modifier::Intersection {
|
||||||
|
for c in (0..self.cursor_pos.2).chain(
|
||||||
|
(std::cmp::min(self.length, self.cursor_pos.2 + amount) + 1)
|
||||||
|
..self.length,
|
||||||
|
) {
|
||||||
|
if let Some(env_hash) = self.get_env_under_cursor(c) {
|
||||||
|
self.rows
|
||||||
|
.update_selection_with_env(env_hash, |e| *e = false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
PageMovement::PageDown(multiplier) => {
|
||||||
|
for c in self.cursor_pos.2
|
||||||
|
..std::cmp::min(self.cursor_pos.2 + rows * multiplier, self.length)
|
||||||
|
{
|
||||||
|
if let Some(env_hash) = self.get_env_under_cursor(c) {
|
||||||
|
self.rows.update_selection_with_env(
|
||||||
|
env_hash,
|
||||||
|
match modifier {
|
||||||
|
Modifier::SymmetricDifference => {
|
||||||
|
|e: &mut bool| *e = !*e
|
||||||
|
}
|
||||||
|
Modifier::Union => |e: &mut bool| *e = true,
|
||||||
|
Modifier::Difference => |e: &mut bool| *e = false,
|
||||||
|
Modifier::Intersection => |_: &mut bool| {},
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if modifier == Modifier::Intersection {
|
||||||
|
for c in (0..self.cursor_pos.2).chain(
|
||||||
|
(std::cmp::min(
|
||||||
|
self.cursor_pos.2 + rows * multiplier,
|
||||||
|
self.length,
|
||||||
|
) + 1)..self.length,
|
||||||
|
) {
|
||||||
|
if let Some(env_hash) = self.get_env_under_cursor(c) {
|
||||||
|
self.rows
|
||||||
|
.update_selection_with_env(env_hash, |e| *e = false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
PageMovement::Right(_) | PageMovement::Left(_) => {}
|
||||||
|
PageMovement::Home => {
|
||||||
|
for c in 0..=self.cursor_pos.2 {
|
||||||
|
if let Some(env_hash) = self.get_env_under_cursor(c) {
|
||||||
|
self.rows.update_selection_with_env(
|
||||||
|
env_hash,
|
||||||
|
match modifier {
|
||||||
|
Modifier::SymmetricDifference => {
|
||||||
|
|e: &mut bool| *e = !*e
|
||||||
|
}
|
||||||
|
Modifier::Union => |e: &mut bool| *e = true,
|
||||||
|
Modifier::Difference => |e: &mut bool| *e = false,
|
||||||
|
Modifier::Intersection => |_: &mut bool| {},
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if modifier == Modifier::Intersection {
|
||||||
|
for c in (self.cursor_pos.2)..self.length {
|
||||||
|
if let Some(env_hash) = self.get_env_under_cursor(c) {
|
||||||
|
self.rows
|
||||||
|
.update_selection_with_env(env_hash, |e| *e = false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
PageMovement::End => {
|
||||||
|
for c in self.cursor_pos.2..self.length {
|
||||||
|
if let Some(env_hash) = self.get_env_under_cursor(c) {
|
||||||
|
self.rows.update_selection_with_env(
|
||||||
|
env_hash,
|
||||||
|
match modifier {
|
||||||
|
Modifier::SymmetricDifference => {
|
||||||
|
|e: &mut bool| *e = !*e
|
||||||
|
}
|
||||||
|
Modifier::Union => |e: &mut bool| *e = true,
|
||||||
|
Modifier::Difference => |e: &mut bool| *e = false,
|
||||||
|
Modifier::Intersection => |_: &mut bool| {},
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if modifier == Modifier::Intersection {
|
||||||
|
for c in 0..self.cursor_pos.2 {
|
||||||
|
if let Some(env_hash) = self.get_env_under_cursor(c) {
|
||||||
|
self.rows
|
||||||
|
.update_selection_with_env(env_hash, |e| *e = false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
self.force_draw = true;
|
||||||
|
}
|
||||||
|
|
||||||
if !self.rows.row_updates.is_empty() {
|
if !self.rows.row_updates.is_empty() {
|
||||||
let (upper_left, bottom_right) = area;
|
|
||||||
while let Some(env_hash) = self.rows.row_updates.pop() {
|
while let Some(env_hash) = self.rows.row_updates.pop() {
|
||||||
let row: usize = self.rows.env_order[&env_hash];
|
let row: usize = self.rows.env_order[&env_hash];
|
||||||
let rows = get_y(bottom_right) - get_y(upper_left) + 1;
|
let envelope: EnvelopeRef = context.accounts[&self.cursor_pos.0]
|
||||||
|
.collection
|
||||||
|
.get_env(env_hash);
|
||||||
|
let row_attr = row_attr!(
|
||||||
|
self.color_cache,
|
||||||
|
row % 2 == 0,
|
||||||
|
!envelope.is_seen(),
|
||||||
|
false,
|
||||||
|
self.rows.selection[&env_hash]
|
||||||
|
);
|
||||||
|
self.rows.row_attr_cache.insert(row, row_attr);
|
||||||
let page_no = (self.new_cursor_pos.2).wrapping_div(rows);
|
let page_no = (self.new_cursor_pos.2).wrapping_div(rows);
|
||||||
|
|
||||||
let top_idx = page_no * rows;
|
let top_idx = page_no * rows;
|
||||||
if row >= top_idx && row <= top_idx + rows {
|
self.force_draw |= row >= top_idx && row < top_idx + rows;
|
||||||
let new_area = nth_row_area(area, row % rows);
|
|
||||||
self.data_columns.draw(
|
|
||||||
grid,
|
|
||||||
row,
|
|
||||||
self.cursor_pos.2,
|
|
||||||
grid.bounds_iter(new_area),
|
|
||||||
);
|
|
||||||
let envelope: EnvelopeRef = context.accounts[&self.cursor_pos.0]
|
|
||||||
.collection
|
|
||||||
.get_env(env_hash);
|
|
||||||
let row_attr = row_attr!(
|
|
||||||
self.color_cache,
|
|
||||||
row % 2 == 0,
|
|
||||||
!envelope.is_seen(),
|
|
||||||
false,
|
|
||||||
self.rows.selection[&env_hash]
|
|
||||||
);
|
|
||||||
self.rows.row_attr_cache.insert(row, row_attr);
|
|
||||||
|
|
||||||
change_colors(grid, new_area, row_attr.fg, row_attr.bg);
|
|
||||||
context.dirty_areas.push_back(new_area);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if self.force_draw {
|
if self.force_draw {
|
||||||
/* Draw the entire list */
|
/* Draw the entire list */
|
||||||
|
@ -1149,6 +1308,7 @@ impl Component for PlainListing {
|
||||||
self.modifier_command = Some(Modifier::default());
|
self.modifier_command = Some(Modifier::default());
|
||||||
} else if let Some(env_hash) = self.get_env_under_cursor(self.cursor_pos.2) {
|
} else if let Some(env_hash) = self.get_env_under_cursor(self.cursor_pos.2) {
|
||||||
self.rows.update_selection_with_env(env_hash, |e| *e = !*e);
|
self.rows.update_selection_with_env(env_hash, |e| *e = !*e);
|
||||||
|
self.set_dirty(true);
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1505,6 +1505,7 @@ impl Component for ThreadListing {
|
||||||
self.modifier_command = Some(Modifier::default());
|
self.modifier_command = Some(Modifier::default());
|
||||||
} else if let Some(env_hash) = self.get_env_under_cursor(self.cursor_pos.2) {
|
} else if let Some(env_hash) = self.get_env_under_cursor(self.cursor_pos.2) {
|
||||||
self.rows.update_selection_with_env(env_hash, |e| *e = !*e);
|
self.rows.update_selection_with_env(env_hash, |e| *e = !*e);
|
||||||
|
self.set_dirty(true);
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue