1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98
use gtk::prelude::IsA;
use std::fmt::Debug;
/// A trait implemented for GTK4 widgets that allows a factory to create and remove widgets.
pub trait FactoryView: IsA<gtk::Widget> {
/// The widget returned when inserting a widget.
///
/// This doesn't matter on containers like [`gtk::Box`].
/// However, widgets such as [`gtk::Stack`] return a [`gtk::StackPage`]
/// which might be used to set additional parameters.
///
/// Therefore, this "returned widget" is explicitly handled here.
type ReturnedWidget: Debug + std::hash::Hash;
/// Widget type that is attached to the container
/// and also the root of the components.
type Children: Debug + AsRef<Self::Children>;
/// Position type used by this widget.
///
/// For example [`GridPosition`] for [`gtk::Grid`] or `()` for [`gtk::Box`]
///
/// [`GridPosition`]: crate::factory::positions::GridPosition
type Position;
/// Removes a widget.
fn factory_remove(&self, widget: &Self::ReturnedWidget);
/// Adds a new widget to self at the end.
fn factory_append(
&self,
widget: impl AsRef<Self::Children>,
position: &Self::Position,
) -> Self::ReturnedWidget;
/// Add an widget to the front.
fn factory_prepend(
&self,
widget: impl AsRef<Self::Children>,
position: &Self::Position,
) -> Self::ReturnedWidget;
/// Insert a widget after another widget.
fn factory_insert_after(
&self,
widget: impl AsRef<Self::Children>,
position: &Self::Position,
other: &Self::ReturnedWidget,
) -> Self::ReturnedWidget;
/// Converts a returned widget to the children type.
///
fn returned_widget_to_child(root_child: &Self::ReturnedWidget) -> Self::Children;
/// Move an item after another item.
fn factory_move_after(&self, widget: &Self::ReturnedWidget, other: &Self::ReturnedWidget);
/// Move an item to the start.
fn factory_move_start(&self, widget: &Self::ReturnedWidget);
/// Update the position inside positioned containers like [`gtk::Grid`].
fn factory_update_position(&self, _widget: &Self::ReturnedWidget, _position: &Self::Position) {}
}
/// Returns the position of an element inside a
/// container like [`gtk::Grid`] where the position isn't
/// clearly defined by the index.
pub trait Position<Pos> {
/// Returns the position.
///
/// This function can be called very often
/// if widgets are moved a lot, so it should
/// be cheap to call.
fn position(&self, index: usize) -> Pos;
}
impl<C> Position<()> for C {
fn position(&self, _index: usize) {}
}
/// Returns the position of an element inside a
/// container like [`gtk::Grid`] where the position isn't
/// clearly defined by the index.
///
/// Unlike [`Position`], this trait doesn't get access to self,
/// because the model might not be initialized when the widgets
/// are updated in the factory.
pub trait AsyncPosition<Pos> {
/// Returns the position.
///
/// This function can be called very often
/// if widgets are moved a lot, so it should
/// be cheap to call.
fn position(index: usize) -> Pos;
}
impl<C> AsyncPosition<()> for C {
fn position(_index: usize) {}
}