Add query signal to search entry

This commit is contained in:
Elias Projahn 2023-09-30 19:10:32 +02:00
parent 7eacfe21f4
commit 54f0088e61
3 changed files with 48 additions and 4 deletions

View file

@ -22,9 +22,11 @@ template $MusicusSearchEntry : Gtk.Box {
hexpand: true; hexpand: true;
activate => $activate() swapped; activate => $activate() swapped;
backspace => $backspace() swapped; backspace => $backspace() swapped;
changed => $text_changed() swapped;
} }
Gtk.Image clear_icon { Gtk.Image clear_icon {
visible: false;
icon-name: "edit-clear-symbolic"; icon-name: "edit-clear-symbolic";
tooltip-text: _("Clear entry"); tooltip-text: _("Clear entry");
} }

View file

@ -53,6 +53,10 @@ mod imp {
self.search_entry.set_key_capture_widget(&*self.obj()); self.search_entry.set_key_capture_widget(&*self.obj());
self.search_entry.connect_query_changed(|entry| {
log::info!("{}", entry.query());
});
self.player self.player
.borrow() .borrow()
.bind_property("active", &self.play_button.get(), "visible") .bind_property("active", &self.play_button.get(), "visible")

View file

@ -1,7 +1,7 @@
use crate::search_tag::MusicusSearchTag; use crate::search_tag::MusicusSearchTag;
use adw::{gdk, glib, glib::clone, glib::subclass::Signal, prelude::*, subclass::prelude::*}; use adw::{gdk, gio, glib, glib::clone, glib::subclass::Signal, prelude::*, subclass::prelude::*};
use once_cell::sync::Lazy; use once_cell::sync::Lazy;
use std::cell::RefCell; use std::{cell::RefCell, time::Duration};
mod imp { mod imp {
use super::*; use super::*;
@ -17,6 +17,7 @@ mod imp {
pub clear_icon: TemplateChild<gtk::Image>, pub clear_icon: TemplateChild<gtk::Image>,
pub tags: RefCell<Vec<MusicusSearchTag>>, pub tags: RefCell<Vec<MusicusSearchTag>>,
pub query_changed: RefCell<Option<gio::Cancellable>>,
} }
#[glib::object_subclass] #[glib::object_subclass]
@ -70,8 +71,12 @@ mod imp {
} }
fn signals() -> &'static [Signal] { fn signals() -> &'static [Signal] {
static SIGNALS: Lazy<Vec<Signal>> = static SIGNALS: Lazy<Vec<Signal>> = Lazy::new(|| {
Lazy::new(|| vec![Signal::builder("activate").build()]); vec![
Signal::builder("activate").build(),
Signal::builder("query-changed").build(),
]
});
SIGNALS.as_ref() SIGNALS.as_ref()
} }
@ -97,6 +102,14 @@ impl MusicusSearchEntry {
glib::Object::new() glib::Object::new()
} }
pub fn connect_query_changed<F: Fn(&Self) + 'static>(&self, f: F) -> glib::SignalHandlerId {
self.connect_local("query-changed", true, move |values| {
let obj = values[0].get::<Self>().unwrap();
f(&obj);
None
})
}
pub fn set_key_capture_widget(&self, widget: &impl IsA<gtk::Widget>) { pub fn set_key_capture_widget(&self, widget: &impl IsA<gtk::Widget>) {
let controller = gtk::EventControllerKey::new(); let controller = gtk::EventControllerKey::new();
@ -134,6 +147,10 @@ impl MusicusSearchEntry {
self.imp().tags.borrow_mut().push(tag); self.imp().tags.borrow_mut().push(tag);
} }
pub fn query(&self) -> String {
self.imp().text.text().to_string()
}
#[template_callback] #[template_callback]
fn activate(&self, _: &gtk::Text) { fn activate(&self, _: &gtk::Text) {
self.emit_by_name::<()>("activate", &[]); self.emit_by_name::<()>("activate", &[]);
@ -147,4 +164,25 @@ impl MusicusSearchEntry {
} }
} }
} }
#[template_callback]
async fn text_changed(&self, text: &gtk::Text) {
self.imp().clear_icon.set_visible(!text.text().is_empty());
if let Some(cancellable) = self.imp().query_changed.borrow_mut().take() {
cancellable.cancel();
}
let cancellable = gio::Cancellable::new();
self.imp().query_changed.replace(Some(cancellable.clone()));
let _ = gio::CancellableFuture::new(
async {
glib::timeout_future(Duration::from_millis(150)).await;
self.emit_by_name::<()>("query-changed", &[]);
},
cancellable,
)
.await;
}
} }