libpanel/subclass/
document_workspace.rs

1use super::workspace::WorkspaceImpl;
2use crate::{prelude::*, DocumentWorkspace, Frame, Position, Widget};
3use glib::translate::*;
4use gtk::subclass::prelude::*;
5
6pub trait DocumentWorkspaceImpl: WorkspaceImpl {
7    fn create_frame(&self, position: &Position) -> Frame {
8        DocumentWorkspaceImplExt::parent_create_frame(self, position)
9    }
10    fn add_widget(&self, widget: &Widget, position: &Position) -> bool {
11        DocumentWorkspaceImplExt::parent_add_widget(self, widget, position)
12    }
13}
14
15pub trait DocumentWorkspaceImplExt: ObjectSubclass {
16    fn parent_create_frame(&self, position: &Position) -> Frame;
17    fn parent_add_widget(&self, widget: &Widget, position: &Position) -> bool;
18}
19
20impl<T: DocumentWorkspaceImpl> DocumentWorkspaceImplExt for T {
21    fn parent_create_frame(&self, position: &Position) -> Frame {
22        unsafe {
23            let data = T::type_data();
24            let parent_class =
25                data.as_ref().parent_class() as *mut ffi::PanelDocumentWorkspaceClass;
26            let f = (*parent_class)
27                .create_frame
28                .expect("No parent class implementation for \"create_frame\"");
29            from_glib_full(f(
30                self.obj()
31                    .unsafe_cast_ref::<DocumentWorkspace>()
32                    .to_glib_none()
33                    .0,
34                position.to_glib_none().0,
35            ))
36        }
37    }
38    fn parent_add_widget(&self, widget: &Widget, position: &Position) -> bool {
39        unsafe {
40            let data = T::type_data();
41            let parent_class =
42                data.as_ref().parent_class() as *mut ffi::PanelDocumentWorkspaceClass;
43            if let Some(f) = (*parent_class).add_widget {
44                from_glib(f(
45                    self.obj()
46                        .unsafe_cast_ref::<DocumentWorkspace>()
47                        .to_glib_none()
48                        .0,
49                    widget.to_glib_none().0,
50                    position.to_glib_none().0,
51                ))
52            } else {
53                false
54            }
55        }
56    }
57}
58
59unsafe impl<T: DocumentWorkspaceImpl> IsSubclassable<T> for DocumentWorkspace {
60    fn class_init(class: &mut glib::Class<Self>) {
61        Self::parent_class_init::<T>(class);
62        let klass = class.as_mut();
63        klass.create_frame = Some(panel_document_workspace_create_frame::<T>);
64        klass.add_widget = Some(panel_document_workspace_add_widget::<T>);
65    }
66}
67
68unsafe extern "C" fn panel_document_workspace_create_frame<T: DocumentWorkspaceImpl>(
69    ptr: *mut ffi::PanelDocumentWorkspace,
70    position: *mut ffi::PanelPosition,
71) -> *mut ffi::PanelFrame {
72    let instance = &*(ptr as *mut T::Instance);
73    let imp = instance.imp();
74    let position: Borrowed<Position> = from_glib_borrow(position);
75
76    DocumentWorkspaceImpl::create_frame(imp, &position).to_glib_full()
77}
78
79unsafe extern "C" fn panel_document_workspace_add_widget<T: DocumentWorkspaceImpl>(
80    ptr: *mut ffi::PanelDocumentWorkspace,
81    widget: *mut ffi::PanelWidget,
82    position: *mut ffi::PanelPosition,
83) -> glib::ffi::gboolean {
84    let instance = &*(ptr as *mut T::Instance);
85    let imp = instance.imp();
86    let widget: Borrowed<Widget> = from_glib_borrow(widget);
87    let position: Borrowed<Position> = from_glib_borrow(position);
88
89    DocumentWorkspaceImpl::add_widget(imp, &widget, &position).into_glib()
90}