Skip to content

Commit a071855

Browse files
committed
use ListView for containers
1 parent 0f6fcb3 commit a071855

File tree

4 files changed

+205
-136
lines changed

4 files changed

+205
-136
lines changed

data/gtk/window.ui

Lines changed: 15 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -91,15 +91,21 @@
9191
<object class="GtkStackPage">
9292
<property name="name">distroboxes</property>
9393
<property name="child">
94-
<object class="GtkScrolledWindow">
95-
<property name="child">
96-
<object class="GtkListBox" id="sidebar_list_box">
97-
<property name="selection-mode">single</property>
98-
<style>
99-
<class name="navigation-sidebar"/>
100-
</style>
94+
<object class="GtkBox">
95+
<property name="orientation">vertical</property>
96+
<child>
97+
<object class="GtkScrolledWindow">
98+
<property name="hexpand">True</property>
99+
<property name="vexpand">True</property>
100+
<property name="child">
101+
<object class="GtkListView" id="sidebar_list_view">
102+
<style>
103+
<class name="navigation-sidebar"/>
104+
</style>
105+
</object>
106+
</property>
101107
</object>
102-
</property>
108+
</child>
103109
</object>
104110
</property>
105111
</object>
@@ -116,7 +122,7 @@
116122
</object>
117123
</property>
118124
<property name="content">
119-
<object class="AdwNavigationPage">
125+
<object class="AdwNavigationPage" id="content_page">
120126
<property name="title" translatable="yes">Container</property>
121127
<property name="child">
122128
<object class="AdwToolbarView">

src/sidebar_row.rs

Lines changed: 18 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ mod imp {
2525
pub status_overlay: gtk::Overlay,
2626
pub status_dot: gtk::Box,
2727

28-
#[property(get, set)]
28+
#[property(get, set=Self::set_container)]
2929
pub container: RefCell<Container>,
3030
#[property(get, set=Self::set_status_tag)]
3131
pub status_tag: RefCell<String>,
@@ -34,6 +34,22 @@ mod imp {
3434
}
3535

3636
impl SidebarRow {
37+
fn set_container(&self, value: &Container) {
38+
self.container.replace(value.clone());
39+
// Bind properties
40+
value
41+
.bind_property("status-tag", &self.obj().clone(), "status-tag")
42+
.sync_create()
43+
.build();
44+
value
45+
.bind_property("name", &self.title_label, "label")
46+
.sync_create()
47+
.build();
48+
value
49+
.bind_property("image", &self.obj().clone(), "image")
50+
.sync_create()
51+
.build();
52+
}
3753
fn set_image(&self, value: &str) {
3854
self.image.replace(value.to_string());
3955
distro_icon::set_image(&self.icon, value);
@@ -150,23 +166,7 @@ glib::wrapper! {
150166
impl SidebarRow {
151167
pub fn new(container: &Container) -> Self {
152168
let obj: Self = glib::Object::builder().build();
153-
obj.set_data(container);
169+
obj.set_container(container);
154170
obj
155171
}
156-
157-
fn set_data(&self, container: &Container) {
158-
let imp = self.imp();
159-
container
160-
.bind_property("status-tag", self, "status-tag")
161-
.sync_create()
162-
.build();
163-
container
164-
.bind_property("name", &imp.title_label, "label")
165-
.sync_create()
166-
.build();
167-
container
168-
.bind_property("image", self, "image")
169-
.sync_create()
170-
.build();
171-
}
172172
}

src/store/root_store.rs

Lines changed: 25 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -130,8 +130,7 @@ mod imp {
130130
pub containers_query: Query<Vec<Container>>,
131131

132132
pub containers: TypedListStore<Container>,
133-
#[property(get, set, nullable)]
134-
selected_container: RefCell<Option<crate::container::Container>>,
133+
pub selected_container_model: OnceCell<gtk::SingleSelection>,
135134

136135
pub tasks: TypedListStore<DistroboxTask>,
137136
#[property(get, set, nullable)]
@@ -154,7 +153,7 @@ mod imp {
154153
terminal_repository: RefCell::new(TerminalRepository::new(
155154
CommandRunner::new_null(),
156155
)),
157-
selected_container: Default::default(),
156+
selected_container_model: OnceCell::new(),
158157
current_view: Default::default(),
159158
current_dialog: Default::default(),
160159
distrobox: Default::default(),
@@ -203,6 +202,14 @@ impl RootStore {
203202
.or(Err("distrobox already set"))
204203
.unwrap();
205204

205+
// Initialize the SingleSelection model
206+
let selection = gtk::SingleSelection::new(Some(this.containers().inner().clone()));
207+
this.imp()
208+
.selected_container_model
209+
.set(selection)
210+
.or(Err("selected_container_model already set"))
211+
.unwrap();
212+
206213
let this_clone = this.clone();
207214
this.imp().distrobox_version.set_fetcher(move || {
208215
let this_clone = this_clone.clone();
@@ -242,20 +249,13 @@ impl RootStore {
242249
let this_clone = this.clone();
243250
this.containers_query().connect_success(move |containers| {
244251
let this = this_clone.clone();
245-
let previous_selected = this.selected_container().clone();
246252

247253
reconcile_list_by_key(
248254
this.containers(),
249255
&containers[..],
250256
|item| item.name(),
251257
&["name", "status-tag", "status-detail", "distro", "image"],
252258
);
253-
254-
if previous_selected.is_none() {
255-
if let Some(first) = containers.first() {
256-
this.set_selected_container(Some(first.clone()));
257-
}
258-
}
259259
});
260260

261261
if this.selected_terminal().is_none() {
@@ -306,6 +306,21 @@ impl RootStore {
306306
&self.imp().tasks
307307
}
308308

309+
pub fn selected_container_model(&self) -> gtk::SingleSelection {
310+
self.imp().selected_container_model.get().unwrap().clone()
311+
}
312+
313+
/// Get the currently selected container, if any
314+
pub fn selected_container(&self) -> Option<Container> {
315+
let model = self.selected_container_model();
316+
let position = model.selected();
317+
if position == gtk::INVALID_LIST_POSITION {
318+
None
319+
} else {
320+
model.selected_item().and_then(|obj| obj.downcast::<Container>().ok())
321+
}
322+
}
323+
309324
pub fn load_containers(&self) {
310325
self.containers_query().refetch_if_stale(Duration::from_secs(1));
311326
}

0 commit comments

Comments
 (0)