re_component_ui 0.35.0

Provides ui editors for Rerun component data for registration with the Rerun Viewer component ui registry.
Documentation
use re_data_ui::item_ui::timeline_button;
use re_log::ResultExt as _;
use re_log_types::TimelineName;
use re_sdk_types::blueprint::components::TimelineColumn;
use re_viewer_context::{AppContext, MaybeMutRef};

use crate::visible_dnd::visible_dnd;

/// The (freeform) timeline name stored in the blueprint, if valid (e.g. non-empty).
fn column_timeline_name(col: &TimelineColumn) -> Option<TimelineName> {
    TimelineName::try_new(col.timeline.as_str()).ok_or_log_error_once()
}

pub fn edit_or_view_columns_singleline(
    ctx: &AppContext<'_>,
    ui: &mut egui::Ui,
    columns: &mut MaybeMutRef<'_, Vec<TimelineColumn>>,
) -> egui::Response {
    ui.horizontal(|ui| {
        for col in columns.iter() {
            if *col.visible
                && let Some(timeline) = column_timeline_name(col)
            {
                timeline_button(ctx, ui, &timeline);
            }
        }
    })
    .response
}

pub fn edit_or_view_columns_multiline(
    ctx: &AppContext<'_>,
    ui: &mut egui::Ui,
    columns: &mut MaybeMutRef<'_, Vec<TimelineColumn>>,
) -> egui::Response {
    match columns {
        MaybeMutRef::Ref(columns) => columns
            .iter()
            .filter(|col| col.visible.into())
            .filter_map(|col| {
                column_timeline_name(col).map(|timeline| timeline_button(ctx, ui, &timeline))
            })
            .reduce(|a, b| a.union(b))
            .unwrap_or_else(|| ui.weak("Empty")),

        MaybeMutRef::MutRef(columns) => {
            if let Some(recording) = ctx.active_recording() {
                // Add new timelines to the end of the UI, if there is any edit
                // these will be written to the component.
                let extra_columns = recording
                    .timelines()
                    .values()
                    .filter(|timeline| {
                        columns
                            .iter()
                            .all(|col| col.timeline.as_str() != timeline.name().as_str())
                    })
                    .map(|timeline| {
                        TimelineColumn(re_sdk_types::blueprint::datatypes::TimelineColumn {
                            visible: false.into(),
                            timeline: timeline.name().as_str().into(),
                        })
                    })
                    .collect::<Vec<_>>();

                columns.extend(extra_columns);
            }

            visible_dnd(
                ui,
                "timeline_columns_dnd",
                columns,
                |ui, col| {
                    if let Some(timeline) = column_timeline_name(col) {
                        timeline_button(ctx, ui, &timeline);
                    }
                },
                |col| *col.visible,
                |col, v| col.visible = v.into(),
            )
        }
    }
}