listing: select multiple messages with a motion
- Press a number (movement multiplier) - Press "select_entry" shortcut (default: v) - Press a movement (arrow keys, PageUp/Down, Home/End) - Resulting selection will be symmetric difference of previous selection plus all the entries traversed with movementmaster
parent
9e20f6556a
commit
ed27ed604c
|
@ -376,6 +376,7 @@ pub trait ListingTrait: Component {
|
||||||
_context: &Context,
|
_context: &Context,
|
||||||
) {
|
) {
|
||||||
}
|
}
|
||||||
|
fn set_command_modifier(&mut self, _is_active: bool) {}
|
||||||
fn set_movement(&mut self, mvm: PageMovement);
|
fn set_movement(&mut self, mvm: PageMovement);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -647,12 +648,14 @@ impl Component for Listing {
|
||||||
1
|
1
|
||||||
} else if let Ok(amount) = self.cmd_buf.parse::<usize>() {
|
} else if let Ok(amount) = self.cmd_buf.parse::<usize>() {
|
||||||
self.cmd_buf.clear();
|
self.cmd_buf.clear();
|
||||||
|
self.component.set_command_modifier(false);
|
||||||
context
|
context
|
||||||
.replies
|
.replies
|
||||||
.push_back(UIEvent::StatusEvent(StatusEvent::BufClear));
|
.push_back(UIEvent::StatusEvent(StatusEvent::BufClear));
|
||||||
amount
|
amount
|
||||||
} else {
|
} else {
|
||||||
self.cmd_buf.clear();
|
self.cmd_buf.clear();
|
||||||
|
self.component.set_command_modifier(false);
|
||||||
context
|
context
|
||||||
.replies
|
.replies
|
||||||
.push_back(UIEvent::StatusEvent(StatusEvent::BufClear));
|
.push_back(UIEvent::StatusEvent(StatusEvent::BufClear));
|
||||||
|
@ -698,12 +701,14 @@ impl Component for Listing {
|
||||||
1
|
1
|
||||||
} else if let Ok(amount) = self.cmd_buf.parse::<usize>() {
|
} else if let Ok(amount) = self.cmd_buf.parse::<usize>() {
|
||||||
self.cmd_buf.clear();
|
self.cmd_buf.clear();
|
||||||
|
self.component.set_command_modifier(false);
|
||||||
context
|
context
|
||||||
.replies
|
.replies
|
||||||
.push_back(UIEvent::StatusEvent(StatusEvent::BufClear));
|
.push_back(UIEvent::StatusEvent(StatusEvent::BufClear));
|
||||||
amount
|
amount
|
||||||
} else {
|
} else {
|
||||||
self.cmd_buf.clear();
|
self.cmd_buf.clear();
|
||||||
|
self.component.set_command_modifier(false);
|
||||||
context
|
context
|
||||||
.replies
|
.replies
|
||||||
.push_back(UIEvent::StatusEvent(StatusEvent::BufClear));
|
.push_back(UIEvent::StatusEvent(StatusEvent::BufClear));
|
||||||
|
@ -797,12 +802,14 @@ impl Component for Listing {
|
||||||
1
|
1
|
||||||
} else if let Ok(amount) = self.cmd_buf.parse::<usize>() {
|
} else if let Ok(amount) = self.cmd_buf.parse::<usize>() {
|
||||||
self.cmd_buf.clear();
|
self.cmd_buf.clear();
|
||||||
|
self.component.set_command_modifier(false);
|
||||||
context
|
context
|
||||||
.replies
|
.replies
|
||||||
.push_back(UIEvent::StatusEvent(StatusEvent::BufClear));
|
.push_back(UIEvent::StatusEvent(StatusEvent::BufClear));
|
||||||
amount
|
amount
|
||||||
} else {
|
} else {
|
||||||
self.cmd_buf.clear();
|
self.cmd_buf.clear();
|
||||||
|
self.component.set_command_modifier(false);
|
||||||
context
|
context
|
||||||
.replies
|
.replies
|
||||||
.push_back(UIEvent::StatusEvent(StatusEvent::BufClear));
|
.push_back(UIEvent::StatusEvent(StatusEvent::BufClear));
|
||||||
|
@ -818,12 +825,14 @@ impl Component for Listing {
|
||||||
1
|
1
|
||||||
} else if let Ok(amount) = self.cmd_buf.parse::<usize>() {
|
} else if let Ok(amount) = self.cmd_buf.parse::<usize>() {
|
||||||
self.cmd_buf.clear();
|
self.cmd_buf.clear();
|
||||||
|
self.component.set_command_modifier(false);
|
||||||
context
|
context
|
||||||
.replies
|
.replies
|
||||||
.push_back(UIEvent::StatusEvent(StatusEvent::BufClear));
|
.push_back(UIEvent::StatusEvent(StatusEvent::BufClear));
|
||||||
amount
|
amount
|
||||||
} else {
|
} else {
|
||||||
self.cmd_buf.clear();
|
self.cmd_buf.clear();
|
||||||
|
self.component.set_command_modifier(false);
|
||||||
context
|
context
|
||||||
.replies
|
.replies
|
||||||
.push_back(UIEvent::StatusEvent(StatusEvent::BufClear));
|
.push_back(UIEvent::StatusEvent(StatusEvent::BufClear));
|
||||||
|
@ -839,12 +848,14 @@ impl Component for Listing {
|
||||||
1
|
1
|
||||||
} else if let Ok(mult) = self.cmd_buf.parse::<usize>() {
|
} else if let Ok(mult) = self.cmd_buf.parse::<usize>() {
|
||||||
self.cmd_buf.clear();
|
self.cmd_buf.clear();
|
||||||
|
self.component.set_command_modifier(false);
|
||||||
context
|
context
|
||||||
.replies
|
.replies
|
||||||
.push_back(UIEvent::StatusEvent(StatusEvent::BufClear));
|
.push_back(UIEvent::StatusEvent(StatusEvent::BufClear));
|
||||||
mult
|
mult
|
||||||
} else {
|
} else {
|
||||||
self.cmd_buf.clear();
|
self.cmd_buf.clear();
|
||||||
|
self.component.set_command_modifier(false);
|
||||||
context
|
context
|
||||||
.replies
|
.replies
|
||||||
.push_back(UIEvent::StatusEvent(StatusEvent::BufClear));
|
.push_back(UIEvent::StatusEvent(StatusEvent::BufClear));
|
||||||
|
@ -860,12 +871,14 @@ impl Component for Listing {
|
||||||
1
|
1
|
||||||
} else if let Ok(mult) = self.cmd_buf.parse::<usize>() {
|
} else if let Ok(mult) = self.cmd_buf.parse::<usize>() {
|
||||||
self.cmd_buf.clear();
|
self.cmd_buf.clear();
|
||||||
|
self.component.set_command_modifier(false);
|
||||||
context
|
context
|
||||||
.replies
|
.replies
|
||||||
.push_back(UIEvent::StatusEvent(StatusEvent::BufClear));
|
.push_back(UIEvent::StatusEvent(StatusEvent::BufClear));
|
||||||
mult
|
mult
|
||||||
} else {
|
} else {
|
||||||
self.cmd_buf.clear();
|
self.cmd_buf.clear();
|
||||||
|
self.component.set_command_modifier(false);
|
||||||
context
|
context
|
||||||
.replies
|
.replies
|
||||||
.push_back(UIEvent::StatusEvent(StatusEvent::BufClear));
|
.push_back(UIEvent::StatusEvent(StatusEvent::BufClear));
|
||||||
|
@ -957,12 +970,14 @@ impl Component for Listing {
|
||||||
1
|
1
|
||||||
} else if let Ok(amount) = self.cmd_buf.parse::<usize>() {
|
} else if let Ok(amount) = self.cmd_buf.parse::<usize>() {
|
||||||
self.cmd_buf.clear();
|
self.cmd_buf.clear();
|
||||||
|
self.component.set_command_modifier(false);
|
||||||
context
|
context
|
||||||
.replies
|
.replies
|
||||||
.push_back(UIEvent::StatusEvent(StatusEvent::BufClear));
|
.push_back(UIEvent::StatusEvent(StatusEvent::BufClear));
|
||||||
amount
|
amount
|
||||||
} else {
|
} else {
|
||||||
self.cmd_buf.clear();
|
self.cmd_buf.clear();
|
||||||
|
self.component.set_command_modifier(false);
|
||||||
context
|
context
|
||||||
.replies
|
.replies
|
||||||
.push_back(UIEvent::StatusEvent(StatusEvent::BufClear));
|
.push_back(UIEvent::StatusEvent(StatusEvent::BufClear));
|
||||||
|
@ -1009,12 +1024,14 @@ impl Component for Listing {
|
||||||
1
|
1
|
||||||
} else if let Ok(amount) = self.cmd_buf.parse::<usize>() {
|
} else if let Ok(amount) = self.cmd_buf.parse::<usize>() {
|
||||||
self.cmd_buf.clear();
|
self.cmd_buf.clear();
|
||||||
|
self.component.set_command_modifier(false);
|
||||||
context
|
context
|
||||||
.replies
|
.replies
|
||||||
.push_back(UIEvent::StatusEvent(StatusEvent::BufClear));
|
.push_back(UIEvent::StatusEvent(StatusEvent::BufClear));
|
||||||
amount
|
amount
|
||||||
} else {
|
} else {
|
||||||
self.cmd_buf.clear();
|
self.cmd_buf.clear();
|
||||||
|
self.component.set_command_modifier(false);
|
||||||
context
|
context
|
||||||
.replies
|
.replies
|
||||||
.push_back(UIEvent::StatusEvent(StatusEvent::BufClear));
|
.push_back(UIEvent::StatusEvent(StatusEvent::BufClear));
|
||||||
|
@ -1063,12 +1080,14 @@ impl Component for Listing {
|
||||||
1
|
1
|
||||||
} else if let Ok(amount) = self.cmd_buf.parse::<usize>() {
|
} else if let Ok(amount) = self.cmd_buf.parse::<usize>() {
|
||||||
self.cmd_buf.clear();
|
self.cmd_buf.clear();
|
||||||
|
self.component.set_command_modifier(false);
|
||||||
context
|
context
|
||||||
.replies
|
.replies
|
||||||
.push_back(UIEvent::StatusEvent(StatusEvent::BufClear));
|
.push_back(UIEvent::StatusEvent(StatusEvent::BufClear));
|
||||||
amount
|
amount
|
||||||
} else {
|
} else {
|
||||||
self.cmd_buf.clear();
|
self.cmd_buf.clear();
|
||||||
|
self.component.set_command_modifier(false);
|
||||||
context
|
context
|
||||||
.replies
|
.replies
|
||||||
.push_back(UIEvent::StatusEvent(StatusEvent::BufClear));
|
.push_back(UIEvent::StatusEvent(StatusEvent::BufClear));
|
||||||
|
@ -1131,6 +1150,7 @@ impl Component for Listing {
|
||||||
}
|
}
|
||||||
UIEvent::Input(Key::Esc) | UIEvent::Input(Key::Alt('')) if !self.cmd_buf.is_empty() => {
|
UIEvent::Input(Key::Esc) | UIEvent::Input(Key::Alt('')) if !self.cmd_buf.is_empty() => {
|
||||||
self.cmd_buf.clear();
|
self.cmd_buf.clear();
|
||||||
|
self.component.set_command_modifier(false);
|
||||||
context
|
context
|
||||||
.replies
|
.replies
|
||||||
.push_back(UIEvent::StatusEvent(StatusEvent::BufClear));
|
.push_back(UIEvent::StatusEvent(StatusEvent::BufClear));
|
||||||
|
@ -1138,6 +1158,7 @@ impl Component for Listing {
|
||||||
}
|
}
|
||||||
UIEvent::Input(Key::Char(c)) if c >= '0' && c <= '9' => {
|
UIEvent::Input(Key::Char(c)) if c >= '0' && c <= '9' => {
|
||||||
self.cmd_buf.push(c);
|
self.cmd_buf.push(c);
|
||||||
|
self.component.set_command_modifier(true);
|
||||||
context
|
context
|
||||||
.replies
|
.replies
|
||||||
.push_back(UIEvent::StatusEvent(StatusEvent::BufSet(
|
.push_back(UIEvent::StatusEvent(StatusEvent::BufSet(
|
||||||
|
|
|
@ -160,6 +160,8 @@ pub struct CompactListing {
|
||||||
color_cache: ColorCache,
|
color_cache: ColorCache,
|
||||||
|
|
||||||
movement: Option<PageMovement>,
|
movement: Option<PageMovement>,
|
||||||
|
modifier_active: bool,
|
||||||
|
modifier_command: Option<char>,
|
||||||
id: ComponentId,
|
id: ComponentId,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -858,6 +860,10 @@ impl ListingTrait for CompactListing {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn set_command_modifier(&mut self, is_active: bool) {
|
||||||
|
self.modifier_active = is_active;
|
||||||
|
}
|
||||||
|
|
||||||
fn set_movement(&mut self, mvm: PageMovement) {
|
fn set_movement(&mut self, mvm: PageMovement) {
|
||||||
self.movement = Some(mvm);
|
self.movement = Some(mvm);
|
||||||
self.set_dirty(true);
|
self.set_dirty(true);
|
||||||
|
@ -897,6 +903,8 @@ impl CompactListing {
|
||||||
view: ThreadView::default(),
|
view: ThreadView::default(),
|
||||||
color_cache: ColorCache::default(),
|
color_cache: ColorCache::default(),
|
||||||
movement: None,
|
movement: None,
|
||||||
|
modifier_active: false,
|
||||||
|
modifier_command: None,
|
||||||
id: ComponentId::new_v4(),
|
id: ComponentId::new_v4(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1395,18 +1403,79 @@ impl Component for CompactListing {
|
||||||
|
|
||||||
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('s') = self.modifier_command.take() {
|
||||||
|
self.set_command_modifier(false);
|
||||||
|
if let Some(mvm) = self.movement.as_ref() {
|
||||||
|
match mvm {
|
||||||
|
PageMovement::Up(amount) => {
|
||||||
|
for c in self.new_cursor_pos.2.saturating_sub(*amount)
|
||||||
|
..=self.new_cursor_pos.2
|
||||||
|
{
|
||||||
|
let thread = self.get_thread_under_cursor(c);
|
||||||
|
self.selection.entry(thread).and_modify(|e| *e = !*e);
|
||||||
|
self.row_updates.push(thread);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
PageMovement::PageUp(multiplier) => {
|
||||||
|
for c in self.new_cursor_pos.2.saturating_sub(rows * multiplier)
|
||||||
|
..=self.new_cursor_pos.2
|
||||||
|
{
|
||||||
|
let thread = self.get_thread_under_cursor(c);
|
||||||
|
self.selection.entry(thread).and_modify(|e| *e = !*e);
|
||||||
|
self.row_updates.push(thread);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
PageMovement::Down(amount) => {
|
||||||
|
for c in self.new_cursor_pos.2
|
||||||
|
..std::cmp::min(self.length, self.new_cursor_pos.2 + amount + 1)
|
||||||
|
{
|
||||||
|
let thread = self.get_thread_under_cursor(c);
|
||||||
|
self.selection.entry(thread).and_modify(|e| *e = !*e);
|
||||||
|
self.row_updates.push(thread);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
PageMovement::PageDown(multiplier) => {
|
||||||
|
for c in self.new_cursor_pos.2
|
||||||
|
..std::cmp::min(
|
||||||
|
self.new_cursor_pos.2 + rows * multiplier + 1,
|
||||||
|
self.length,
|
||||||
|
)
|
||||||
|
{
|
||||||
|
let thread = self.get_thread_under_cursor(c);
|
||||||
|
self.selection.entry(thread).and_modify(|e| *e = !*e);
|
||||||
|
self.row_updates.push(thread);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
PageMovement::Right(_) | PageMovement::Left(_) => {}
|
||||||
|
PageMovement::Home => {
|
||||||
|
for c in 0..=self.new_cursor_pos.2 {
|
||||||
|
let thread = self.get_thread_under_cursor(c);
|
||||||
|
self.selection.entry(thread).and_modify(|e| *e = !*e);
|
||||||
|
self.row_updates.push(thread);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
PageMovement::End => {
|
||||||
|
for c in self.new_cursor_pos.2..self.length {
|
||||||
|
let thread = self.get_thread_under_cursor(c);
|
||||||
|
self.selection.entry(thread).and_modify(|e| *e = !*e);
|
||||||
|
self.row_updates.push(thread);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if !self.row_updates.is_empty() {
|
if !self.row_updates.is_empty() {
|
||||||
let (upper_left, bottom_right) = area;
|
|
||||||
while let Some(row) = self.row_updates.pop() {
|
while let Some(row) = self.row_updates.pop() {
|
||||||
self.update_line(context, row);
|
self.update_line(context, row);
|
||||||
let row: usize = self.order[&row];
|
let row: usize = self.order[&row];
|
||||||
|
|
||||||
let rows = get_y(bottom_right) - get_y(upper_left) + 1;
|
|
||||||
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 {
|
if row >= top_idx && row < top_idx + rows {
|
||||||
let area = (
|
let area = (
|
||||||
set_y(upper_left, get_y(upper_left) + (row % rows)),
|
set_y(upper_left, get_y(upper_left) + (row % rows)),
|
||||||
set_y(bottom_right, get_y(upper_left) + (row % rows)),
|
set_y(bottom_right, get_y(upper_left) + (row % rows)),
|
||||||
|
@ -1475,8 +1544,13 @@ impl Component for CompactListing {
|
||||||
key == shortcuts[CompactListing::DESCRIPTION]["select_entry"]
|
key == shortcuts[CompactListing::DESCRIPTION]["select_entry"]
|
||||||
) =>
|
) =>
|
||||||
{
|
{
|
||||||
let thread_hash = self.get_thread_under_cursor(self.cursor_pos.2);
|
if self.modifier_active {
|
||||||
self.selection.entry(thread_hash).and_modify(|e| *e = !*e);
|
self.modifier_command = Some('s');
|
||||||
|
} else {
|
||||||
|
let thread_hash = self.get_thread_under_cursor(self.cursor_pos.2);
|
||||||
|
self.selection.entry(thread_hash).and_modify(|e| *e = !*e);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
UIEvent::Action(ref action) => {
|
UIEvent::Action(ref action) => {
|
||||||
match action {
|
match action {
|
||||||
|
|
|
@ -123,6 +123,8 @@ pub struct ConversationsListing {
|
||||||
color_cache: ColorCache,
|
color_cache: ColorCache,
|
||||||
|
|
||||||
movement: Option<PageMovement>,
|
movement: Option<PageMovement>,
|
||||||
|
modifier_active: bool,
|
||||||
|
modifier_command: Option<char>,
|
||||||
id: ComponentId,
|
id: ComponentId,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -848,6 +850,10 @@ impl ListingTrait for ConversationsListing {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn set_command_modifier(&mut self, is_active: bool) {
|
||||||
|
self.modifier_active = is_active;
|
||||||
|
}
|
||||||
|
|
||||||
fn set_movement(&mut self, mvm: PageMovement) {
|
fn set_movement(&mut self, mvm: PageMovement) {
|
||||||
self.movement = Some(mvm);
|
self.movement = Some(mvm);
|
||||||
self.set_dirty(true);
|
self.set_dirty(true);
|
||||||
|
@ -884,6 +890,8 @@ impl ConversationsListing {
|
||||||
view: ThreadView::default(),
|
view: ThreadView::default(),
|
||||||
color_cache: ColorCache::default(),
|
color_cache: ColorCache::default(),
|
||||||
movement: None,
|
movement: None,
|
||||||
|
modifier_active: false,
|
||||||
|
modifier_command: None,
|
||||||
id: ComponentId::new_v4(),
|
id: ComponentId::new_v4(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1201,20 +1209,81 @@ impl Component for ConversationsListing {
|
||||||
|
|
||||||
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) / 3;
|
||||||
|
if let Some('s') = self.modifier_command.take() {
|
||||||
|
self.set_command_modifier(false);
|
||||||
|
if let Some(mvm) = self.movement.as_ref() {
|
||||||
|
match mvm {
|
||||||
|
PageMovement::Up(amount) => {
|
||||||
|
for c in self.new_cursor_pos.2.saturating_sub(*amount)
|
||||||
|
..=self.new_cursor_pos.2
|
||||||
|
{
|
||||||
|
let thread = self.get_thread_under_cursor(c);
|
||||||
|
self.selection.entry(thread).and_modify(|e| *e = !*e);
|
||||||
|
self.row_updates.push(thread);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
PageMovement::PageUp(multiplier) => {
|
||||||
|
for c in self.new_cursor_pos.2.saturating_sub(rows * multiplier)
|
||||||
|
..=self.new_cursor_pos.2
|
||||||
|
{
|
||||||
|
let thread = self.get_thread_under_cursor(c);
|
||||||
|
self.selection.entry(thread).and_modify(|e| *e = !*e);
|
||||||
|
self.row_updates.push(thread);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
PageMovement::Down(amount) => {
|
||||||
|
for c in self.new_cursor_pos.2
|
||||||
|
..std::cmp::min(self.length, self.new_cursor_pos.2 + amount + 1)
|
||||||
|
{
|
||||||
|
let thread = self.get_thread_under_cursor(c);
|
||||||
|
self.selection.entry(thread).and_modify(|e| *e = !*e);
|
||||||
|
self.row_updates.push(thread);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
PageMovement::PageDown(multiplier) => {
|
||||||
|
for c in self.new_cursor_pos.2
|
||||||
|
..std::cmp::min(
|
||||||
|
self.new_cursor_pos.2 + rows * multiplier + 1,
|
||||||
|
self.length,
|
||||||
|
)
|
||||||
|
{
|
||||||
|
let thread = self.get_thread_under_cursor(c);
|
||||||
|
self.selection.entry(thread).and_modify(|e| *e = !*e);
|
||||||
|
self.row_updates.push(thread);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
PageMovement::Right(_) | PageMovement::Left(_) => {}
|
||||||
|
PageMovement::Home => {
|
||||||
|
for c in 0..=self.new_cursor_pos.2 {
|
||||||
|
let thread = self.get_thread_under_cursor(c);
|
||||||
|
self.selection.entry(thread).and_modify(|e| *e = !*e);
|
||||||
|
self.row_updates.push(thread);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
PageMovement::End => {
|
||||||
|
for c in self.new_cursor_pos.2..self.length {
|
||||||
|
let thread = self.get_thread_under_cursor(c);
|
||||||
|
self.selection.entry(thread).and_modify(|e| *e = !*e);
|
||||||
|
self.row_updates.push(thread);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
if !self.row_updates.is_empty() {
|
if !self.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)
|
||||||
* */
|
* */
|
||||||
let (upper_left, bottom_right) = area;
|
|
||||||
while let Some(row) = self.row_updates.pop() {
|
while let Some(row) = self.row_updates.pop() {
|
||||||
self.update_line(context, row);
|
self.update_line(context, row);
|
||||||
let row: usize = self.order[&row];
|
let row: usize = self.order[&row];
|
||||||
|
|
||||||
let rows = (get_y(bottom_right) - get_y(upper_left) + 1) / 3;
|
|
||||||
let page_no = (self.cursor_pos.2).wrapping_div(rows);
|
let page_no = (self.cursor_pos.2).wrapping_div(rows);
|
||||||
|
|
||||||
let top_idx = page_no * rows;
|
let top_idx = page_no * rows;
|
||||||
/* Update row only if it's currently visible */
|
/* Update row only if it's currently visible */
|
||||||
if row >= top_idx && row <= top_idx + rows {
|
if row >= top_idx && row < top_idx + rows {
|
||||||
let area = (
|
let area = (
|
||||||
set_y(upper_left, get_y(upper_left) + (3 * (row % rows))),
|
set_y(upper_left, get_y(upper_left) + (3 * (row % rows))),
|
||||||
set_y(bottom_right, get_y(upper_left) + (3 * (row % rows) + 2)),
|
set_y(bottom_right, get_y(upper_left) + (3 * (row % rows) + 2)),
|
||||||
|
@ -1288,8 +1357,12 @@ impl Component for ConversationsListing {
|
||||||
key == shortcuts[ConversationsListing::DESCRIPTION]["select_entry"]
|
key == shortcuts[ConversationsListing::DESCRIPTION]["select_entry"]
|
||||||
) =>
|
) =>
|
||||||
{
|
{
|
||||||
let thread = self.get_thread_under_cursor(self.cursor_pos.2);
|
if self.modifier_active {
|
||||||
self.selection.entry(thread).and_modify(|e| *e = !*e);
|
self.modifier_command = Some('s');
|
||||||
|
} else {
|
||||||
|
let thread = self.get_thread_under_cursor(self.cursor_pos.2);
|
||||||
|
self.selection.entry(thread).and_modify(|e| *e = !*e);
|
||||||
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
UIEvent::EnvelopeRename(ref old_hash, ref new_hash) => {
|
UIEvent::EnvelopeRename(ref old_hash, ref new_hash) => {
|
||||||
|
|
Loading…
Reference in New Issue