Skip to content

Commit

Permalink
Merge pull request #70 from luleyleo/highlights
Browse files Browse the repository at this point in the history
Highlight matches in results
  • Loading branch information
luleyleo authored Feb 22, 2025
2 parents d6c2206 + 1680d4c commit d553eff
Show file tree
Hide file tree
Showing 7 changed files with 176 additions and 34 deletions.
3 changes: 2 additions & 1 deletion assets/de.leopoldluley.Clapgrep.metainfo.xml.in.in
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,8 @@
<description translate="no">
<p>New features:</p>
<ul>
<li>Implmented PDF preview.</li>
<li>Matches are now highlighted and easier to spot.</li>
<li>The preview no supports PDF files.</li>
<li>Much faster PDF search using Poppler.</li>
<li>PDF results are now per line rather than per page.</li>
</ul>
Expand Down
3 changes: 3 additions & 0 deletions gnome/src/ui/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,7 @@ pub use error_window::ErrorWindow;
mod search_window;
pub use search_window::SearchWindow;

mod result_view;
pub use result_view::ResultView;

mod preview;
113 changes: 113 additions & 0 deletions gnome/src/ui/result_view/imp.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
use crate::search::{SearchMatch, SearchResult};
use adw::subclass::prelude::*;
use glib::subclass::InitializingObject;
use gtk::{glib, pango, prelude::*, CompositeTemplate};
use std::cell::{Cell, RefCell};

#[derive(Default, Clone, Copy)]
struct Color {
pub r: u16,
pub g: u16,
pub b: u16,
}

#[derive(CompositeTemplate, glib::Properties, Default)]
#[template(file = "src/ui/result_view/result_view.blp")]
#[properties(wrapper_type = super::ResultView)]
pub struct ResultView {
#[property(get, set)]
pub result: RefCell<Option<SearchResult>>,

#[template_child]
pub content: TemplateChild<gtk::Label>,

highlight_color: Cell<Color>,
}

#[glib::object_subclass]
impl ObjectSubclass for ResultView {
const NAME: &'static str = "ClapgrepResultView";
type Type = super::ResultView;
type ParentType = gtk::Widget;

fn class_init(klass: &mut Self::Class) {
klass.bind_template();
}

fn instance_init(obj: &InitializingObject<Self>) {
obj.init_template();
}
}

impl ResultView {
fn update_color(&self, style_manager: &adw::StyleManager) {
let dark = style_manager.is_dark();
let accent_color = style_manager.accent_color().to_standalone_rgba(dark);
let accent_color = Color {
r: (accent_color.red() * (0xFFFF as f32)) as u16,
g: (accent_color.green() * (0xFFFF as f32)) as u16,
b: (accent_color.blue() * (0xFFFF as f32)) as u16,
};
self.highlight_color.set(accent_color);
}

fn update_content(&self) {
let highlight_color = self.highlight_color.get();

let result = self.result.borrow();
if let Some(result) = result.as_ref() {
let content = result.content();
self.content.set_text(&content);

let matches = result.matches();
if let Some(matches) = matches {
let attributes = pango::AttrList::new();
for m in matches.iter::<SearchMatch>() {
let m = m.expect("expected SearchMatch");
let mut highlight = pango::AttrColor::new_foreground(
highlight_color.r,
highlight_color.g,
highlight_color.b,
);
highlight.set_start_index(m.start());
highlight.set_end_index(m.end());
attributes.insert(highlight);
}
self.content.set_attributes(Some(&attributes));
}
}
}
}

#[glib::derived_properties]
impl ObjectImpl for ResultView {
fn constructed(&self) {
self.parent_constructed();
let obj = self.obj();

let style_manager = adw::StyleManager::default();
style_manager.connect_accent_color_notify(glib::clone!(
#[weak]
obj,
move |style_manager| {
obj.imp().update_color(style_manager);
obj.imp().update_content();
}
));
style_manager.connect_dark_notify(glib::clone!(
#[weak]
obj,
move |style_manager| {
obj.imp().update_color(style_manager);
obj.imp().update_content();
}
));
obj.imp().update_color(&style_manager);

obj.connect_result_notify(|obj| {
obj.imp().update_content();
});
}
}

impl WidgetImpl for ResultView {}
17 changes: 17 additions & 0 deletions gnome/src/ui/result_view/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
mod imp;

use glib::Object;
use gtk::glib;

use crate::search::SearchResult;

glib::wrapper! {
pub struct ResultView(ObjectSubclass<imp::ResultView>)
@extends gtk::Widget;
}

impl ResultView {
pub fn new(result: &SearchResult) -> Self {
Object::builder().property("result", result).build()
}
}
37 changes: 37 additions & 0 deletions gnome/src/ui/result_view/result_view.blp
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
using Gtk 4.0;

template $ClapgrepResultView: Widget {
layout-manager: Gtk.BinLayout {};

Box {
orientation: horizontal;
margin-top: 2;
margin-start: 16;
margin-end: 16;
margin-bottom: 2;

Label {
xalign: 1.0;
width-request: 40;
label: bind template.result as <$ClapgrepSearchResult>.line;

styles [
"monospace"
]
}

Label {
label: ": ";

styles [
"monospace"
]
}

Label content {
styles [
"monospace"
]
}
}
}
3 changes: 2 additions & 1 deletion gnome/src/ui/search_window/imp.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ use crate::{
config::Config,
i18n::gettext_f,
search::{SearchModel, SearchResult},
ui::{preview::Preview, ErrorWindow},
ui::{preview::Preview, ErrorWindow, ResultView},
APP_ID,
};
use adw::subclass::prelude::*;
Expand Down Expand Up @@ -99,6 +99,7 @@ impl ObjectSubclass for SearchWindow {
type ParentType = adw::ApplicationWindow;

fn class_init(klass: &mut Self::Class) {
ResultView::static_type();
klass.bind_template();
klass.bind_template_callbacks();
klass.install_action("win.start-search", None, |win, _, _| {
Expand Down
34 changes: 2 additions & 32 deletions gnome/src/ui/search_window/search_window.blp
Original file line number Diff line number Diff line change
Expand Up @@ -225,38 +225,8 @@ template $ClapgrepSearchWindow: Adw.ApplicationWindow {

factory: BuilderListItemFactory {
template ListItem {
child: Box {
orientation: horizontal;
margin-top: 2;
margin-start: 16;
margin-end: 16;
margin-bottom: 2;

Label {
xalign: 1.0;
width-request: 40;
label: bind template.item as <$ClapgrepSearchResult>.line;

styles [
"monospace"
]
}

Label {
label: ": ";

styles [
"monospace"
]
}

Label {
label: bind template.item as <$ClapgrepSearchResult>.content;

styles [
"monospace"
]
}
child: $ClapgrepResultView {
result: bind template.item;
};
}
};
Expand Down

0 comments on commit d553eff

Please sign in to comment.