Skip to content

Commit ecc8567

Browse files
gtk: Add SectionModel subclassing support
1 parent af9f9ad commit ecc8567

File tree

2 files changed

+78
-0
lines changed

2 files changed

+78
-0
lines changed

gtk4/src/subclass/mod.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,9 @@ pub mod root;
6868
pub mod scale;
6969
pub mod scale_button;
7070
pub mod scrollable;
71+
#[cfg(any(feature = "v4_12", docsrs))]
72+
#[cfg_attr(docsrs, doc(cfg(feature = "v4_12")))]
73+
pub mod section_model;
7174
pub mod selection_model;
7275
pub mod shortcut_manager;
7376
pub mod sorter;
@@ -150,6 +153,9 @@ pub mod prelude {
150153
pub use super::scale::{ScaleImpl, ScaleImplExt};
151154
pub use super::scale_button::{ScaleButtonImpl, ScaleButtonImplExt};
152155
pub use super::scrollable::{ScrollableImpl, ScrollableImplExt};
156+
#[cfg(any(feature = "v4_12", docsrs))]
157+
#[cfg_attr(docsrs, doc(cfg(feature = "v4_12")))]
158+
pub use super::section_model::{SectionModelImpl, SectionModelImplExt};
153159
pub use super::selection_model::{SelectionModelImpl, SelectionModelImplExt};
154160
pub use super::shortcut_manager::{ShortcutManagerImpl, ShortcutManagerImplExt};
155161
pub use super::sorter::{SorterImpl, SorterImplExt};

gtk4/src/subclass/section_model.rs

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
// Take a look at the license at the top of the repository in the LICENSE file.
2+
3+
// rustdoc-stripper-ignore-next
4+
//! Traits intended for implementing the [`SectionModel`](crate::SectionModel) interface.
5+
6+
use crate::{prelude::*, subclass::prelude::*, SectionModel};
7+
use glib::translate::*;
8+
9+
pub trait SectionModelImpl: ListModelImpl {
10+
#[doc(alias = "get_section")]
11+
fn section(&self, position: u32) -> (u32, u32) {
12+
self.parent_section(position)
13+
}
14+
}
15+
16+
mod sealed {
17+
pub trait Sealed {}
18+
impl<T: super::SectionModelImplExt> Sealed for T {}
19+
}
20+
21+
pub trait SectionModelImplExt: sealed::Sealed + ObjectSubclass {
22+
fn parent_section(&self, position: u32) -> (u32, u32) {
23+
unsafe {
24+
let type_data = Self::type_data();
25+
let parent_iface = type_data.as_ref().parent_interface::<SectionModel>()
26+
as *const ffi::GtkSectionModelInterface;
27+
28+
let func = (*parent_iface)
29+
.get_section
30+
.expect("no parent \"get_section\" implementation");
31+
32+
let mut start = std::mem::MaybeUninit::uninit();
33+
let mut end = std::mem::MaybeUninit::uninit();
34+
func(
35+
self.obj()
36+
.unsafe_cast_ref::<SectionModel>()
37+
.to_glib_none()
38+
.0,
39+
position,
40+
start.as_mut_ptr(),
41+
end.as_mut_ptr(),
42+
);
43+
(start.assume_init(), end.assume_init())
44+
}
45+
}
46+
}
47+
48+
impl<T: SectionModelImpl> SectionModelImplExt for T {}
49+
50+
unsafe impl<T: SectionModelImpl> IsImplementable<T> for SectionModel {
51+
fn interface_init(iface: &mut glib::Interface<Self>) {
52+
let iface = iface.as_mut();
53+
54+
assert_initialized_main_thread!();
55+
56+
iface.get_section = Some(model_get_section::<T>);
57+
}
58+
}
59+
60+
unsafe extern "C" fn model_get_section<T: SectionModelImpl>(
61+
model: *mut ffi::GtkSectionModel,
62+
position: u32,
63+
startptr: *mut libc::c_uint,
64+
endptr: *mut libc::c_uint,
65+
) {
66+
let instance = &*(model as *mut T::Instance);
67+
let imp = instance.imp();
68+
69+
let (start, end) = imp.section(position);
70+
*startptr = start;
71+
*endptr = end;
72+
}

0 commit comments

Comments
 (0)