mod container;
mod iter_children;
mod object_ext;
mod remove;
mod set_child;
#[cfg(test)]
mod tests;
mod widget_ext;
pub use container::RelmContainerExt;
pub use iter_children::RelmIterChildrenExt;
pub use object_ext::RelmObjectExt;
pub use remove::{RelmRemoveAllExt, RelmRemoveExt};
pub use set_child::RelmSetChildExt;
pub use widget_ext::RelmWidgetExt;
use gtk::prelude::{
ApplicationExt, ApplicationExtManual, Cast, IsA, ListBoxRowExt, StaticType, WidgetExt,
};
pub trait WidgetRef {
fn widget_ref(&self) -> >k::Widget;
}
impl<T: AsRef<gtk::Widget>> WidgetRef for T {
fn widget_ref(&self) -> >k::Widget {
self.as_ref()
}
}
pub trait WidgetTemplate:
Sized + std::fmt::Debug + AsRef<Self::Root> + std::ops::Deref<Target = Self::Root>
{
type Root;
type Init;
fn init(init: Self::Init) -> Self;
}
pub trait ApplicationBuilderExt {
fn launch<F>(self, init: F)
where
F: Fn(gtk::Application, gtk::ApplicationWindow) + 'static;
}
impl ApplicationBuilderExt for gtk::builders::ApplicationBuilder {
fn launch<F>(self, init: F)
where
F: Fn(gtk::Application, gtk::ApplicationWindow) + 'static,
{
let app = self.build();
app.connect_activate(move |app| {
let window = gtk::ApplicationWindow::new(app);
init(app.clone(), window.clone());
window.set_visible(true);
});
app.run();
}
}
pub trait RelmListBoxExt {
fn index_of_child(&self, widget: &impl AsRef<gtk::Widget>) -> Option<i32>;
fn remove_row_of_child(&self, widget: &impl AsRef<gtk::Widget>);
fn row_of_child(&self, widget: &impl AsRef<gtk::Widget>) -> Option<gtk::ListBoxRow>;
}
impl RelmListBoxExt for gtk::ListBox {
fn index_of_child(&self, widget: &impl AsRef<gtk::Widget>) -> Option<i32> {
self.row_of_child(widget).map(|row| row.index())
}
fn remove_row_of_child(&self, widget: &impl AsRef<gtk::Widget>) {
if let Some(row) = self.row_of_child(widget) {
row.set_child(None::<>k::Widget>);
self.remove(&row);
}
}
fn row_of_child(&self, widget: &impl AsRef<gtk::Widget>) -> Option<gtk::ListBoxRow> {
if let Some(row) = widget.as_ref().ancestor(gtk::ListBoxRow::static_type()) {
if let Some(row) = row.downcast_ref::<gtk::ListBoxRow>() {
if let Some(parent_widget) = row.parent() {
if let Some(parent_box) = parent_widget.downcast_ref::<Self>() {
if parent_box == self {
return Some(row.clone());
}
}
}
}
}
None
}
}
pub trait ContainerChild {
type Child: IsA<gtk::Widget>;
}
macro_rules! container_child_impl {
($($type:ty: $child:ty), +) => {
$(
impl ContainerChild for $type {
type Child = $child;
}
)+
};
($($type:ty), +) => {
$(
#[allow(deprecated)]
impl ContainerChild for $type {
type Child = gtk::Widget;
}
)+
};
}
container_child_impl! {
gtk::Box,
gtk::Fixed,
gtk::Grid,
gtk::ActionBar,
gtk::Stack,
gtk::HeaderBar,
gtk::InfoBar,
gtk::Button,
gtk::ComboBox,
gtk::FlowBoxChild,
gtk::Frame,
gtk::Popover,
gtk::Window,
gtk::ApplicationWindow,
gtk::ListBoxRow,
gtk::ScrolledWindow,
gtk::Dialog,
gtk::LinkButton,
gtk::ToggleButton,
gtk::Overlay,
gtk::Revealer,
gtk::WindowHandle,
gtk::Expander,
gtk::AspectFrame
}
container_child_impl! {
gtk::ListBox: gtk::ListBoxRow,
gtk::FlowBox: gtk::FlowBoxChild
}
#[cfg(feature = "libadwaita")]
#[cfg_attr(docsrs, doc(cfg(feature = "libadwaita")))]
mod libadwaita {
use super::ContainerChild;
container_child_impl! {
adw::TabView,
adw::Window,
adw::Bin,
adw::ApplicationWindow,
adw::Clamp,
adw::ClampScrollable,
adw::SplitButton,
adw::StatusPage,
adw::PreferencesGroup,
adw::ToastOverlay,
adw::ExpanderRow,
adw::Carousel,
adw::Squeezer,
adw::Leaflet
}
#[cfg(all(feature = "libadwaita", feature = "gnome_45"))]
mod gnome_45 {
use super::ContainerChild;
container_child_impl! {
adw::NavigationView: adw::NavigationPage,
adw::NavigationSplitView: adw::NavigationPage
}
container_child_impl! {
adw::NavigationPage,
adw::BreakpointBin,
adw::OverlaySplitView,
adw::ToolbarView
}
}
}