use re_entity_db::InstancePath;
use re_log_types::StoreKind;
use re_viewer_context::{CollapseScope, ContainerId, Item, ItemContext, ViewId};
use crate::collapse_expand::{
collapse_expand_container, collapse_expand_data_result, collapse_expand_instance_path,
collapse_expand_view,
};
use crate::{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::View(_) | 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 {
Self::CollapseAll => "Collapse all".to_owned(),
Self::ExpandAll => "Expand all".to_owned(),
}
}
fn process_container(&self, ctx: &ContextMenuContext<'_>, container_id: &ContainerId) {
let scope = blueprint_collapse_scope(ctx, &Item::Container(*container_id));
collapse_expand_container(
ctx.viewer_context,
ctx.viewport_blueprint,
container_id,
scope,
self.open(),
);
}
fn process_view(&self, ctx: &ContextMenuContext<'_>, view_id: &ViewId) {
let scope = blueprint_collapse_scope(ctx, &Item::View(*view_id));
collapse_expand_view(ctx.viewer_context, view_id, scope, self.open());
}
fn process_data_result(
&self,
ctx: &ContextMenuContext<'_>,
view_id: &ViewId,
instance_path: &InstancePath,
) {
let scope =
blueprint_collapse_scope(ctx, &Item::DataResult(*view_id, instance_path.clone()));
collapse_expand_data_result(
ctx.viewer_context,
view_id,
instance_path,
scope,
self.open(),
);
}
fn process_instance_path(&self, ctx: &ContextMenuContext<'_>, instance_path: &InstancePath) {
let (db, scope) = match ctx
.selection
.context_for_item(&Item::InstancePath(instance_path.clone()))
{
Some(&ItemContext::StreamsTree {
store_kind: StoreKind::Recording,
filter_session_id: Some(session_id),
}) => (
ctx.viewer_context.recording(),
CollapseScope::StreamsTreeFiltered { session_id },
),
Some(&ItemContext::StreamsTree {
store_kind: StoreKind::Blueprint,
filter_session_id: None,
}) => (
ctx.viewer_context.blueprint_db(),
CollapseScope::BlueprintStreamsTree,
),
Some(&ItemContext::StreamsTree {
store_kind: StoreKind::Blueprint,
filter_session_id: Some(session_id),
}) => (
ctx.viewer_context.blueprint_db(),
CollapseScope::BlueprintStreamsTreeFiltered { session_id },
),
Some(
&ItemContext::StreamsTree {
store_kind: StoreKind::Recording,
filter_session_id: None,
}
| &ItemContext::TwoD { .. }
| &ItemContext::ThreeD { .. }
| &ItemContext::BlueprintTree { .. },
)
| None => (ctx.viewer_context.recording(), CollapseScope::StreamsTree),
};
collapse_expand_instance_path(ctx.viewer_context, db, instance_path, scope, self.open());
}
}
impl CollapseExpandAllAction {
fn open(&self) -> bool {
match self {
Self::CollapseAll => false,
Self::ExpandAll => true,
}
}
}
fn blueprint_collapse_scope(ctx: &ContextMenuContext<'_>, item: &Item) -> CollapseScope {
match ctx.selection.context_for_item(item) {
Some(&ItemContext::BlueprintTree {
filter_session_id: Some(session_id),
}) => CollapseScope::BlueprintTreeFiltered { session_id },
None
| Some(
&ItemContext::BlueprintTree {
filter_session_id: None,
}
| &ItemContext::StreamsTree { .. }
| &ItemContext::TwoD { .. }
| &ItemContext::ThreeD { .. },
) => CollapseScope::BlueprintTree,
}
}