dialog: Add search
This commit is contained in:
parent
606f1294c3
commit
36d61d574d
1 changed files with 104 additions and 7 deletions
111
src/dialog.rs
111
src/dialog.rs
|
|
@ -304,6 +304,10 @@ enum Message {
|
||||||
NotifyWatcher(WatcherWrapper),
|
NotifyWatcher(WatcherWrapper),
|
||||||
Open,
|
Open,
|
||||||
Save(bool),
|
Save(bool),
|
||||||
|
SearchActivate,
|
||||||
|
SearchClear,
|
||||||
|
SearchInput(String),
|
||||||
|
SearchSubmit,
|
||||||
TabMessage(tab::Message),
|
TabMessage(tab::Message),
|
||||||
TabRescan(Vec<tab::Item>),
|
TabRescan(Vec<tab::Item>),
|
||||||
ViewSelect(segmented_button::Entity),
|
ViewSelect(segmented_button::Entity),
|
||||||
|
|
@ -349,6 +353,9 @@ struct App {
|
||||||
nav_model: segmented_button::SingleSelectModel,
|
nav_model: segmented_button::SingleSelectModel,
|
||||||
result_opt: Option<DialogResult>,
|
result_opt: Option<DialogResult>,
|
||||||
replace_dialog: bool,
|
replace_dialog: bool,
|
||||||
|
search_active: bool,
|
||||||
|
search_id: widget::Id,
|
||||||
|
search_input: String,
|
||||||
tab: Tab,
|
tab: Tab,
|
||||||
key_binds: HashMap<KeyBind, Action>,
|
key_binds: HashMap<KeyBind, Action>,
|
||||||
view_model: segmented_button::SingleSelectModel,
|
view_model: segmented_button::SingleSelectModel,
|
||||||
|
|
@ -373,6 +380,21 @@ impl App {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn search(&mut self) -> Command<Message> {
|
||||||
|
match &self.tab.location {
|
||||||
|
Location::Path(path) | Location::Search(path, ..) => {
|
||||||
|
let location = if !self.search_input.is_empty() {
|
||||||
|
Location::Search(path.clone(), self.search_input.clone())
|
||||||
|
} else {
|
||||||
|
Location::Path(path.clone())
|
||||||
|
};
|
||||||
|
self.tab.change_location(&location, None);
|
||||||
|
Command::batch([self.update_watcher(), self.rescan_tab()])
|
||||||
|
}
|
||||||
|
_ => Command::none(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn update_config(&mut self) -> Command<Message> {
|
fn update_config(&mut self) -> Command<Message> {
|
||||||
self.update_nav_model();
|
self.update_nav_model();
|
||||||
Command::none()
|
Command::none()
|
||||||
|
|
@ -591,6 +613,9 @@ impl Application for App {
|
||||||
nav_model: segmented_button::ModelBuilder::default().build(),
|
nav_model: segmented_button::ModelBuilder::default().build(),
|
||||||
result_opt: None,
|
result_opt: None,
|
||||||
replace_dialog: false,
|
replace_dialog: false,
|
||||||
|
search_active: false,
|
||||||
|
search_id: widget::Id::unique(),
|
||||||
|
search_input: String::new(),
|
||||||
tab,
|
tab,
|
||||||
key_binds: HashMap::new(),
|
key_binds: HashMap::new(),
|
||||||
view_model,
|
view_model,
|
||||||
|
|
@ -632,16 +657,38 @@ impl Application for App {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn header_end(&self) -> Vec<Element<Message>> {
|
fn header_end(&self) -> Vec<Element<Message>> {
|
||||||
vec![
|
let mut elements = Vec::with_capacity(3);
|
||||||
/*TODO: search and new folder buttons
|
|
||||||
widget::button::icon(widget::icon::from_name("system-search-symbolic")).into(),
|
if self.search_active {
|
||||||
widget::button::icon(widget::icon::from_name("folder-new-symbolic")).into(),
|
elements.push(
|
||||||
*/
|
widget::text_input::search_input("", &self.search_input)
|
||||||
|
.width(Length::Fixed(240.0))
|
||||||
|
.id(self.search_id.clone())
|
||||||
|
.on_clear(Message::SearchClear)
|
||||||
|
.on_input(Message::SearchInput)
|
||||||
|
.on_submit(Message::SearchSubmit)
|
||||||
|
.into(),
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
elements.push(
|
||||||
|
widget::button::icon(widget::icon::from_name("system-search-symbolic"))
|
||||||
|
.on_press(Message::SearchActivate)
|
||||||
|
.into(),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
/*TODO: new folder button
|
||||||
|
elements.push(widget::button::icon(widget::icon::from_name("folder-new-symbolic")).into());
|
||||||
|
*/
|
||||||
|
|
||||||
|
elements.push(
|
||||||
widget::segmented_control::horizontal(&self.view_model)
|
widget::segmented_control::horizontal(&self.view_model)
|
||||||
.on_activate(Message::ViewSelect)
|
.on_activate(Message::ViewSelect)
|
||||||
.width(Length::Shrink)
|
.width(Length::Shrink)
|
||||||
.into(),
|
.into(),
|
||||||
]
|
);
|
||||||
|
|
||||||
|
elements
|
||||||
}
|
}
|
||||||
|
|
||||||
fn nav_bar(&self) -> Option<Element<message::Message<Self::Message>>> {
|
fn nav_bar(&self) -> Option<Element<message::Message<Self::Message>>> {
|
||||||
|
|
@ -682,7 +729,8 @@ impl Application for App {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn on_nav_select(&mut self, entity: segmented_button::Entity) -> Command<Message> {
|
fn on_nav_select(&mut self, entity: segmented_button::Entity) -> Command<Message> {
|
||||||
let location_opt = self.nav_model.data::<Location>(entity).clone();
|
self.search_active = false;
|
||||||
|
self.search_input.clear();
|
||||||
|
|
||||||
self.nav_model.activate(entity);
|
self.nav_model.activate(entity);
|
||||||
if let Some(location) = self.nav_model.data::<Location>(entity) {
|
if let Some(location) = self.nav_model.data::<Location>(entity) {
|
||||||
|
|
@ -699,6 +747,26 @@ impl Application for App {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn on_escape(&mut self) -> Command<Message> {
|
fn on_escape(&mut self) -> Command<Message> {
|
||||||
|
if self.search_active {
|
||||||
|
// Close search if open
|
||||||
|
self.search_active = false;
|
||||||
|
return Command::none();
|
||||||
|
}
|
||||||
|
|
||||||
|
if self.tab.context_menu.is_some() {
|
||||||
|
self.tab.context_menu = None;
|
||||||
|
return Command::none();
|
||||||
|
}
|
||||||
|
|
||||||
|
let had_focused_button = self.tab.select_focus_id().is_some();
|
||||||
|
if self.tab.select_none() {
|
||||||
|
if had_focused_button {
|
||||||
|
// Unfocus if there was a focused button
|
||||||
|
return widget::button::focus(widget::Id::unique());
|
||||||
|
}
|
||||||
|
return Command::none();
|
||||||
|
}
|
||||||
|
|
||||||
self.update(Message::Cancel)
|
self.update(Message::Cancel)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -939,6 +1007,35 @@ impl Application for App {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Message::SearchActivate => {
|
||||||
|
self.search_active = true;
|
||||||
|
return widget::text_input::focus(self.search_id.clone());
|
||||||
|
}
|
||||||
|
Message::SearchClear => {
|
||||||
|
self.search_active = false;
|
||||||
|
self.search_input.clear();
|
||||||
|
}
|
||||||
|
Message::SearchInput(input) => {
|
||||||
|
if input != self.search_input {
|
||||||
|
self.search_input = input;
|
||||||
|
/*TODO: live search? (probably needs subscription for streaming results)
|
||||||
|
// This performs live search
|
||||||
|
if !self.search_input.is_empty() {
|
||||||
|
return self.search();
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Message::SearchSubmit => {
|
||||||
|
if !self.search_input.is_empty() {
|
||||||
|
return self.search();
|
||||||
|
} else {
|
||||||
|
// rescan the tab to get the contents back
|
||||||
|
// and exit search
|
||||||
|
self.search_active = false;
|
||||||
|
return self.search();
|
||||||
|
}
|
||||||
|
}
|
||||||
Message::TabMessage(tab_message) => {
|
Message::TabMessage(tab_message) => {
|
||||||
let click_i_opt = match tab_message {
|
let click_i_opt = match tab_message {
|
||||||
tab::Message::Click(click_i_opt) => click_i_opt,
|
tab::Message::Click(click_i_opt) => click_i_opt,
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue