When click column header binded to sorter, column view became blank if selected item is out of sight.
pub fn make_process_list() -> ColumnView {
let store = gio::ListStore::with_type(ProcessObject::static_type());
for process in get_processes() {
store.append(&process);
}
let list_model: gio::ListModel = store.upcast();
let sort_model = gtk4::SortListModel::new(Some(list_model), None::<gtk4::Sorter>);
let selection_model = SingleSelection::new(Some(sort_model));
let column_view = ColumnView::builder()
.model(&selection_model)
.show_row_separators(true)
.show_column_separators(true)
.build();
add_column(&column_view, "PID", "pid");
add_column(&column_view, "User", "user");
add_column(&column_view, "Name", "name");
add_column(&column_view, "Command", "command");
let view_sorter = column_view.sorter();
let model = column_view.model().unwrap();
let selection_model = model.downcast_ref::<SingleSelection>().unwrap();
let list_model = selection_model.model().unwrap();
let sort_model = list_model.downcast_ref::<SortListModel>().unwrap();
sort_model.set_sorter(view_sorter.as_ref());
column_view.sorter().expect("no sorter").connect_changed({
move |_sorter, _change| {
println!("sorter changed");
}
});
column_view
}
fn add_column(column_view: &ColumnView, title: &str, property: &'static str) {
let factory = SignalListItemFactory::new();
factory.connect_setup(move |_, list_item| {
let list_item = list_item.downcast_ref::<gtk4::ListItem>().unwrap();
let label = Label::builder()
.xalign(0.0)
.margin_start(4)
.margin_end(4)
.build();
list_item.set_child(Some(&label));
let item = list_item.property_expression("item");
item.chain_property::<ProcessObject>(property)
.bind(&label, "label", Widget::NONE);
});
let sorter = gtk4::CustomSorter::new(move |a, b| {
let a_val = a.property::<String>(property);
let b_val = b.property::<String>(property);
if a_val.is_empty() || b_val.is_empty() {
return gtk4::Ordering::Equal;
}
match a_val.cmp(&b_val) {
std::cmp::Ordering::Less => gtk4::Ordering::Smaller,
std::cmp::Ordering::Equal => gtk4::Ordering::Equal,
std::cmp::Ordering::Greater => gtk4::Ordering::Larger,
}
});
let column = ColumnViewColumn::builder()
.title(title)
.factory(&factory)
.sorter(&sorter)
.build();
column_view.append_column(&column);
}