Skip to content

Commit

Permalink
Add some documentation to egui_flex
Browse files Browse the repository at this point in the history
  • Loading branch information
lucasmerlin committed Sep 20, 2024
1 parent a8eb622 commit adae654
Show file tree
Hide file tree
Showing 2 changed files with 60 additions and 7 deletions.
54 changes: 48 additions & 6 deletions crates/egui_flex/src/flex_widget.rs
Original file line number Diff line number Diff line change
@@ -1,15 +1,57 @@
use crate::{FlexContainerResponse, FlexContainerUi};
use egui::{Ui, Widget};
use egui::Ui;

/// Implement this trait for a widget to make it usable in a flex container.
///
/// The reason there is a separate trait is that we need to measure the content size independently
/// of the frame size. (The content will stay at it's intrinsic size while the frame will be
/// stretched according to the flex layout.)
///
/// If your widget has no frmae you don't need to implement this trait and can use
/// [`crate::FlexInstance::add_widget`] to add any [`egui::Widget`].
pub trait FlexWidget {
type Response;
fn ui(self, ui: &mut Ui, container: FlexContainerUi) -> FlexContainerResponse<Self::Response>;
/// Show your widget here. Use the provided [`Ui`] to draw the container (e.g. using a [`egui::Frame`])
/// and in the frame ui use [`FlexContainerUi::content`] to draw your widget.
/// The frame will grow according to the flex layout while the content will be centered / positioned
/// based on [`crate::FlexItem::align_self_content`].
fn flex_ui(
self,
ui: &mut Ui,
container: FlexContainerUi,
) -> FlexContainerResponse<Self::Response>;
}

impl<T: Widget> FlexWidget for T {
type Response = egui::Response;
mod egui_widgets {
use super::*;
use egui::widgets::*;
macro_rules! impl_widget {
($($widget:ty),*) => {
$(
impl FlexWidget for $widget {
type Response = egui::Response;

fn ui(self, ui: &mut Ui, container: FlexContainerUi) -> FlexContainerResponse<Self::Response> {
container.content_widget(ui, self)
fn flex_ui(self, ui: &mut Ui, container: FlexContainerUi) -> FlexContainerResponse<Self::Response> {
container.content_widget(ui, self)
}
}
)*
};
}
impl_widget!(
Button<'_>,
Label,
Checkbox<'_>,
Image<'_>,
DragValue<'_>,
Hyperlink,
ImageButton<'_>,
ProgressBar,
RadioButton,
Link,
SelectableLabel,
Slider<'_>,
TextEdit<'_>,
Spinner
);
}
13 changes: 12 additions & 1 deletion crates/egui_flex/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -688,8 +688,19 @@ impl<'a> FlexInstance<'a> {
self.add_container(item, |ui, container| container.content(ui, content))
}

/// Add a [`FlexWidget`] to the flex container.
/// [`FlexWidget`] is implemented for all default egui widgets.
/// If you use a custom third party widget you can use [`Self::add_widget`] instead.
pub fn add<W: FlexWidget>(&mut self, item: FlexItem, widget: W) -> InnerResponse<W::Response> {
self.add_container(item, |ui, container| widget.ui(ui, container))
self.add_container(item, |ui, container| widget.flex_ui(ui, container))
}

/// Add a [`egui::Widget`] to the flex container.
/// The default egui widgets implement [`FlexWidget`] Aso you can just use [`Self::add`] instead.
/// If the widget reports it's intrinsic size via the [`egui::Response`] it will be able to
/// grow it's frame according to the flex layout.
pub fn add_widget<W: Widget>(&mut self, item: FlexItem, widget: W) -> InnerResponse<Response> {
self.add_container(item, |ui, container| container.content_widget(ui, widget))
}

pub fn add_frame<R>(
Expand Down

0 comments on commit adae654

Please sign in to comment.