Skip to content

Commit 028aaf6

Browse files
authored
Merge pull request #144 from justinbarclay/master
Add max page sized to select
2 parents 030c5f6 + 37221fd commit 028aaf6

File tree

7 files changed

+96
-7
lines changed

7 files changed

+96
-7
lines changed

examples/multi_select.rs

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,4 +23,20 @@ fn main() {
2323
println!(" {}", multiselected[selection]);
2424
}
2525
}
26+
27+
let selections = MultiSelect::with_theme(&ColorfulTheme::default())
28+
.with_prompt("Pick your food")
29+
.items(&multiselected[..])
30+
.defaults(&defaults[..])
31+
.max_length(2)
32+
.interact()
33+
.unwrap();
34+
if selections.is_empty() {
35+
println!("You did not select anything :(");
36+
} else {
37+
println!("You selected these things:");
38+
for selection in selections {
39+
println!(" {}", multiselected[selection]);
40+
}
41+
}
2642
}

examples/select.rs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,4 +29,14 @@ fn main() {
2929
} else {
3030
println!("You didn't select anything!");
3131
}
32+
33+
let selection = Select::with_theme(&ColorfulTheme::default())
34+
.with_prompt("Optionally pick your flavor, hint it might be on the second page")
35+
.default(0)
36+
.max_length(2)
37+
.items(&selections[..])
38+
.interact()
39+
.unwrap();
40+
41+
println!("Enjoy your {}!", selections[selection]);
3242
}

examples/sort.rs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,4 +17,16 @@ fn main() {
1717
println!(" {}", list[sorted[0]]);
1818
println!("Your least favorite item:");
1919
println!(" {}", list[sorted[sorted.len() - 1]]);
20+
21+
let sorted = Sort::with_theme(&ColorfulTheme::default())
22+
.with_prompt("Order your foods by preference")
23+
.items(&list[..])
24+
.max_length(2)
25+
.interact()
26+
.unwrap();
27+
28+
println!("Your favorite item:");
29+
println!(" {}", list[sorted[0]]);
30+
println!("Your least favorite item:");
31+
println!(" {}", list[sorted[sorted.len() - 1]]);
2032
}

src/paging.rs

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,18 +11,23 @@ pub struct Paging<'a> {
1111
pub current_page: usize,
1212
pub capacity: usize,
1313
pub active: bool,
14-
14+
pub max_capacity: Option<usize>,
1515
term: &'a Term,
1616
current_term_size: (u16, u16),
1717
items_len: usize,
1818
activity_transition: bool,
1919
}
2020

2121
impl<'a> Paging<'a> {
22-
pub fn new(term: &'a Term, items_len: usize) -> Paging<'a> {
22+
pub fn new(term: &'a Term, items_len: usize, max_capacity: Option<usize>) -> Paging<'a> {
2323
let term_size = term.size();
2424
// Subtract -2 because we need space to render the prompt, if paging is active
25-
let capacity = term_size.0 as usize - 2;
25+
let capacity = max_capacity
26+
.unwrap_or(std::usize::MAX)
27+
.min(term_size.0 as usize)
28+
// Safeguard in case term_size or max_length is 2 or less. Guarantees no unwanted wrapping behavior.
29+
.max(3)
30+
- 2;
2631
let pages = (items_len as f64 / capacity as f64).ceil() as usize;
2732

2833
Paging {
@@ -33,6 +38,7 @@ impl<'a> Paging<'a> {
3338
term,
3439
current_term_size: term_size,
3540
items_len,
41+
max_capacity,
3642
// Set transition initially to true to trigger prompt rendering for inactive paging on start
3743
activity_transition: true,
3844
}
@@ -44,7 +50,12 @@ impl<'a> Paging<'a> {
4450

4551
if self.current_term_size != new_term_size {
4652
self.current_term_size = new_term_size;
47-
self.capacity = self.current_term_size.0 as usize - 2;
53+
self.capacity = self
54+
.max_capacity
55+
.unwrap_or(std::usize::MAX)
56+
.min(self.current_term_size.0 as usize)
57+
.max(3)
58+
- 2;
4859
self.pages = (self.items_len as f64 / self.capacity as f64).ceil() as usize;
4960
}
5061

src/prompts/multi_select.rs

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ pub struct MultiSelect<'a> {
2626
items: Vec<String>,
2727
prompt: Option<String>,
2828
clear: bool,
29+
max_length: Option<usize>,
2930
theme: &'a dyn Theme,
3031
}
3132

@@ -63,6 +64,18 @@ impl MultiSelect<'_> {
6364
self
6465
}
6566

67+
/// Sets an optional max length for a page
68+
///
69+
/// Max length is disabled by None
70+
pub fn max_length(&mut self, val: usize) -> &mut Self {
71+
// Paging subtracts two from the capacity, paging does this to
72+
// make an offset for the page indicator. So to make sure that
73+
// we can show the intended amount of items we need to add two
74+
// to our value.
75+
self.max_length = Some(val + 2);
76+
self
77+
}
78+
6679
/// Add a single item to the selector.
6780
#[inline]
6881
pub fn item<T: ToString>(&mut self, item: T) -> &mut Self {
@@ -182,7 +195,7 @@ impl MultiSelect<'_> {
182195
));
183196
}
184197

185-
let mut paging = Paging::new(term, self.items.len());
198+
let mut paging = Paging::new(term, self.items.len(), self.max_length);
186199
let mut render = TermThemeRenderer::new(term, self.theme);
187200
let mut sel = 0;
188201

@@ -315,6 +328,7 @@ impl<'a> MultiSelect<'a> {
315328
defaults: vec![],
316329
clear: true,
317330
prompt: None,
331+
max_length: None,
318332
theme,
319333
}
320334
}

src/prompts/select.rs

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ pub struct Select<'a> {
4040
prompt: Option<String>,
4141
clear: bool,
4242
theme: &'a dyn Theme,
43+
max_length: Option<usize>,
4344
}
4445

4546
impl Default for Select<'static> {
@@ -71,6 +72,17 @@ impl Select<'_> {
7172
self.default = val;
7273
self
7374
}
75+
/// Sets an optional max length for a page.
76+
///
77+
/// Max length is disabled by None
78+
pub fn max_length(&mut self, val: usize) -> &mut Self {
79+
// Paging subtracts two from the capacity, paging does this to
80+
// make an offset for the page indicator. So to make sure that
81+
// we can show the intended amount of items we need to add two
82+
// to our value.
83+
self.max_length = Some(val + 2);
84+
self
85+
}
7486

7587
/// Add a single item to the selector.
7688
///
@@ -220,7 +232,7 @@ impl Select<'_> {
220232
));
221233
}
222234

223-
let mut paging = Paging::new(term, self.items.len());
235+
let mut paging = Paging::new(term, self.items.len(), self.max_length);
224236
let mut render = TermThemeRenderer::new(term, self.theme);
225237
let mut sel = self.default;
226238

@@ -347,6 +359,7 @@ impl<'a> Select<'a> {
347359
items: vec![],
348360
prompt: None,
349361
clear: true,
362+
max_length: None,
350363
theme,
351364
}
352365
}

src/prompts/sort.rs

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ pub struct Sort<'a> {
2828
items: Vec<String>,
2929
prompt: Option<String>,
3030
clear: bool,
31+
max_length: Option<usize>,
3132
theme: &'a dyn Theme,
3233
}
3334

@@ -53,6 +54,17 @@ impl Sort<'_> {
5354
self
5455
}
5556

57+
/// Sets an optional max length for a page
58+
///
59+
/// Max length is disabled by None
60+
pub fn max_length(&mut self, val: usize) -> &mut Self {
61+
// Paging subtracts two from the capacity, paging does this to
62+
// make an offset for the page indicator. So to make sure that
63+
// we can show the intended amount of items we need to add two
64+
// to our value.
65+
self.max_length = Some(val + 2);
66+
self
67+
}
5668
/// Add a single item to the selector.
5769
pub fn item<T: ToString>(&mut self, item: T) -> &mut Self {
5870
self.items.push(item.to_string());
@@ -155,7 +167,7 @@ impl Sort<'_> {
155167
));
156168
}
157169

158-
let mut paging = Paging::new(term, self.items.len());
170+
let mut paging = Paging::new(term, self.items.len(), self.max_length);
159171
let mut render = TermThemeRenderer::new(term, self.theme);
160172
let mut sel = 0;
161173

@@ -314,6 +326,7 @@ impl<'a> Sort<'a> {
314326
items: vec![],
315327
clear: true,
316328
prompt: None,
329+
max_length: None,
317330
theme,
318331
}
319332
}

0 commit comments

Comments
 (0)