use re_entity_db::InstancePath;
use re_viewer_context::{CollapseScope, ContainerId, Contents, Item, SpaceViewId};
use crate::context_menu::{ContextMenuAction, ContextMenuContext};
pub(crate) enum CollapseExpandAllAction {
CollapseAll,
ExpandAll,
}
impl ContextMenuAction for CollapseExpandAllAction {
fn supports_selection(&self, ctx: &ContextMenuContext<'_>) -> bool {
ctx.selection
.iter()
.any(|(item, _)| self.supports_item(ctx, item))
}
fn supports_item(&self, ctx: &ContextMenuContext<'_>, item: &Item) -> bool {
match item {
Item::AppId(_) | Item::DataSource(_) | Item::StoreId(_) | Item::ComponentPath(_) => {
false
}
Item::SpaceView(_) | Item::Container(_) | Item::InstancePath(_) => true,
Item::DataResult(_, instance_path) => ctx
.viewer_context
.recording()
.tree()
.subtree(&instance_path.entity_path)
.is_some_and(|subtree| !subtree.is_leaf()),
}
}
fn label(&self, _ctx: &ContextMenuContext<'_>) -> String {
match self {
CollapseExpandAllAction::CollapseAll => "Collapse all".to_owned(),
CollapseExpandAllAction::ExpandAll => "Expand all".to_owned(),
}
}
fn process_container(&self, ctx: &ContextMenuContext<'_>, container_id: &ContainerId) {
ctx.viewport_blueprint
.visit_contents_in_container(container_id, &mut |contents, _| match contents {
Contents::Container(container_id) => CollapseScope::BlueprintTree
.container(*container_id)
.set_open(&ctx.egui_context, self.open()),
Contents::SpaceView(space_view_id) => self.process_space_view(ctx, space_view_id),
});
}
fn process_space_view(&self, ctx: &ContextMenuContext<'_>, space_view_id: &SpaceViewId) {
CollapseScope::BlueprintTree
.space_view(*space_view_id)
.set_open(&ctx.egui_context, self.open());
let query_result = ctx.viewer_context.lookup_query_result(*space_view_id);
let result_tree = &query_result.tree;
if let Some(root_node) = result_tree.root_node() {
self.process_data_result(
ctx,
space_view_id,
&InstancePath::entity_all(root_node.data_result.entity_path.clone()),
);
}
}
fn process_data_result(
&self,
ctx: &ContextMenuContext<'_>,
space_view_id: &SpaceViewId,
instance_path: &InstancePath,
) {
let Some(subtree) = ctx
.viewer_context
.recording()
.tree()
.subtree(&instance_path.entity_path)
else {
return;
};
subtree.visit_children_recursively(&mut |entity_path, _| {
CollapseScope::BlueprintTree
.data_result(*space_view_id, entity_path.clone())
.set_open(&ctx.egui_context, self.open());
});
}
fn process_instance_path(&self, ctx: &ContextMenuContext<'_>, instance_path: &InstancePath) {
let Some(subtree) = ctx
.viewer_context
.recording()
.tree()
.subtree(&instance_path.entity_path)
else {
return;
};
subtree.visit_children_recursively(&mut |entity_path, _| {
CollapseScope::StreamsTree
.entity(entity_path.clone())
.set_open(&ctx.egui_context, self.open());
});
}
}
impl CollapseExpandAllAction {
fn open(&self) -> bool {
match self {
CollapseExpandAllAction::CollapseAll => false,
CollapseExpandAllAction::ExpandAll => true,
}
}
}