[model] support single/multiple selection

This commit is contained in:
zhang_ji 2016-06-30 16:52:30 +08:00
parent ac3a0781f4
commit 41dcdc6856
2 changed files with 30 additions and 29 deletions

View file

@ -42,6 +42,7 @@ fn main() {
let mut opts = Options::new();
opts.optopt("b", "bind", "comma seperated keybindings", "ctrl-j:accept,ctrl-k:kill-line");
opts.optflag("h", "help", "print this help menu");
opts.optflag("m", "multi", "Enable Multiple Selection");
let options = match opts.parse(&args[1..]) {
Ok(m) => { m }
@ -62,6 +63,7 @@ fn main() {
let (tx_matched, rx_matched) = channel();
let eb_model = eb.clone();
let mut model = Model::new(eb_model, curse);
if options.opt_present("m") {model.multi_selection = true;}
let eb_matcher = Arc::new(EventBox::new());
let eb_matcher_clone = eb_matcher.clone();
@ -160,7 +162,8 @@ fn main() {
Event::EvActAbort => { break 'outer; }
Event::EvActAccept => {
// break out of the loop and output the selected item.
if model.get_num_selected() <= 0 { model.act_toggle(Some(true)); }
//if model.get_num_selected() <= 0 { model.act_toggle(Some(true)); }
model.act_accept();
break 'outer;
}
Event::EvActBackwardChar => {model.act_backward_char();}
@ -185,17 +188,17 @@ fn main() {
Event::EvActPageUp => {model.act_move_page(1);}
Event::EvActPreviousHistory => {}
Event::EvActSelectAll => {model.act_select_all();}
Event::EvActToggle => {model.act_toggle(None);}
Event::EvActToggle => {model.act_toggle();}
Event::EvActToggleAll => {model.act_toggle_all();}
Event::EvActToggleDown => {
model.act_toggle(None);
model.act_toggle();
model.act_move_line_cursor(-1);
}
Event::EvActToggleIn => {}
Event::EvActToggleOut => {}
Event::EvActToggleSort => {}
Event::EvActToggleUp => {
model.act_toggle(None);
model.act_toggle();
model.act_move_line_cursor(1);
}
Event::EvActUnixLineDiscard => {model.act_line_discard();}

View file

@ -40,7 +40,9 @@ pub struct Model {
pub items: Arc<RwLock<Vec<Item>>>, // all items
selected_indics: HashSet<usize>,
pub matched_items: RefCell<OrderedVec<MatchedItem>>,
processed_percentage: u64,
pub multi_selection: bool,
item_cursor: usize, // the index of matched item currently highlighted.
line_cursor: usize, // line No.
@ -51,7 +53,7 @@ pub struct Model {
width: usize,
height: usize,
tabstop: usize,
pub tabstop: usize,
curses: Curses,
}
@ -68,6 +70,7 @@ impl Model {
selected_indics: HashSet::new(),
matched_items: RefCell::new(OrderedVec::new()),
processed_percentage: 100,
multi_selection: false,
item_cursor: 0,
line_cursor: 0,
hscroll_offset: 0,
@ -234,6 +237,12 @@ impl Model {
//============================================================================
// Actions
pub fn act_accept(&mut self) {
if self.multi_selection {return;}
let index = self.item_cursor;
self.selected_indics.insert(index);
}
pub fn act_add_char(&mut self, ch: char) {
let changed = self.query.add_char(ch);
if changed {
@ -312,6 +321,8 @@ impl Model {
}
pub fn act_select_all(&mut self) {
if !self.multi_selection {return;}
let mut matched_items = self.matched_items.borrow_mut();
for i in 0..matched_items.len() {
self.selected_indics.insert(i);
@ -319,6 +330,8 @@ impl Model {
}
pub fn act_toggle_all(&mut self) {
if !self.multi_selection {return;}
let mut matched_items = self.matched_items.borrow_mut();
let selected = mem::replace(&mut self.selected_indics, HashSet::new());
for i in 0..matched_items.len() {
@ -328,35 +341,20 @@ impl Model {
}
}
pub fn act_toggle(&mut self, selected: Option<bool>) {
pub fn act_toggle(&mut self) {
if !self.multi_selection {return;}
let mut matched_items = self.matched_items.borrow_mut();
let matched = matched_items.get(self.item_cursor);
if matched == None {
return;
}
let index = matched.unwrap().index;
match selected {
Some(true) => {
let _ = self.selected_indics.insert(index);
}
Some(false) => {
let _ = self.selected_indics.remove(&index);
}
None => {
if self.selected_indics.contains(&index) {
let _ = self.selected_indics.remove(&index);
} else {
let _ = self.selected_indics.insert(index);
}
if let Some(matched) = matched_items.get(self.item_cursor) {
let item_index = matched.index;
if self.selected_indics.contains(&item_index) {
self.selected_indics.remove(&item_index);
} else {
self.selected_indics.insert(item_index);
}
}
}
pub fn get_num_selected(&self) -> usize {
self.selected_indics.len()
}
pub fn act_move_line_cursor(&mut self, diff: i32) {
let total_item = self.matched_items.borrow().len() as i32;