mirror of
https://github.com/FliegendeWurst/cursive.git
synced 2024-11-23 17:35:00 +00:00
new example: autocomplete search box (#502)
new example: autocomplete search box
This commit is contained in:
parent
7b579a7d54
commit
3ab4f9b0f7
@ -17,6 +17,7 @@ pretty-bytes = "0.2.2"
|
|||||||
rand = "0.7.3"
|
rand = "0.7.3"
|
||||||
cursive = { path = "../cursive", default-features=false }
|
cursive = { path = "../cursive", default-features=false }
|
||||||
crossbeam-channel = "0.4.2"
|
crossbeam-channel = "0.4.2"
|
||||||
|
lazy_static = "1.4"
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
default = ["cursive/default"]
|
default = ["cursive/default"]
|
||||||
|
94
examples/src/bin/autocomplete.rs
Normal file
94
examples/src/bin/autocomplete.rs
Normal file
@ -0,0 +1,94 @@
|
|||||||
|
use cursive::align::HAlign;
|
||||||
|
use cursive::traits::Scrollable;
|
||||||
|
use cursive::view::{Boxable, Identifiable};
|
||||||
|
use cursive::views::{Dialog, EditView, LinearLayout, SelectView, TextView};
|
||||||
|
use cursive::Cursive;
|
||||||
|
use lazy_static::lazy_static;
|
||||||
|
|
||||||
|
// This example shows a way to implement a (Google-like) autocomplete search box.
|
||||||
|
// Try entering "tok"!
|
||||||
|
|
||||||
|
lazy_static! {
|
||||||
|
static ref CITIES: &'static str = include_str!("../../assets/cities.txt");
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let mut siv = cursive::default();
|
||||||
|
|
||||||
|
siv.add_layer(
|
||||||
|
Dialog::around(
|
||||||
|
LinearLayout::vertical()
|
||||||
|
// the query box is on the top
|
||||||
|
.child(
|
||||||
|
EditView::new()
|
||||||
|
// update results every time the query changes
|
||||||
|
.on_edit(on_edit)
|
||||||
|
// submit the focused (first) item of the matches
|
||||||
|
.on_submit(on_submit)
|
||||||
|
.with_name("query"),
|
||||||
|
)
|
||||||
|
// search results below the input
|
||||||
|
.child(
|
||||||
|
SelectView::new()
|
||||||
|
// shows all cities by default
|
||||||
|
.with_all_str(CITIES.lines())
|
||||||
|
// Sets the callback for when "Enter" is pressed.
|
||||||
|
.on_submit(show_next_window)
|
||||||
|
// Center the text horizontally
|
||||||
|
.h_align(HAlign::Center)
|
||||||
|
.with_name("matches")
|
||||||
|
.scrollable(),
|
||||||
|
)
|
||||||
|
.fixed_height(10),
|
||||||
|
)
|
||||||
|
.button("Quit", Cursive::quit)
|
||||||
|
.title("Where are you from?"),
|
||||||
|
);
|
||||||
|
|
||||||
|
siv.run();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update results according to the query
|
||||||
|
fn on_edit(siv: &mut Cursive, query: &str, _cursor: usize) {
|
||||||
|
let matches = search_fn(CITIES.lines(), query);
|
||||||
|
// Update the `matches` view with the filtered array of cities
|
||||||
|
siv.call_on_name("matches", |v: &mut SelectView| {
|
||||||
|
v.clear();
|
||||||
|
v.add_all_str(matches);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// Filter cities with names containing query string. You can implement your own logic here!
|
||||||
|
fn search_fn<'a, 'b, T: std::iter::IntoIterator<Item = &'a str>>(
|
||||||
|
items: T,
|
||||||
|
query: &'b str,
|
||||||
|
) -> Vec<&'a str> {
|
||||||
|
items
|
||||||
|
.into_iter()
|
||||||
|
.filter(|&item| {
|
||||||
|
let item = item.to_lowercase();
|
||||||
|
let query = query.to_lowercase();
|
||||||
|
item.contains(&query)
|
||||||
|
})
|
||||||
|
.collect()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn on_submit(siv: &mut Cursive, query: &str) {
|
||||||
|
let matches = siv.find_name::<SelectView>("matches").unwrap();
|
||||||
|
if matches.is_empty() {
|
||||||
|
// not all people live in big cities. If none of the cities in the list matches, use the value of the query.
|
||||||
|
show_next_window(siv, query);
|
||||||
|
} else {
|
||||||
|
// pressing "Enter" without moving the focus into the `matches` view will submit the first match result
|
||||||
|
let city = &*matches.selection().unwrap();
|
||||||
|
show_next_window(siv, city);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
fn show_next_window(siv: &mut Cursive, city: &str) {
|
||||||
|
siv.pop_layer();
|
||||||
|
let text = format!("{} is a great city!", city);
|
||||||
|
siv.add_layer(
|
||||||
|
Dialog::around(TextView::new(text)).button("Quit", |s| s.quit()),
|
||||||
|
);
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user