Skip to main content

ferrum_flow/plugins/
focus_selection.rs

1use crate::{
2    plugin::{FlowEvent, Plugin, PluginContext, primary_platform_modifier},
3    plugins::viewport_frame::frame_world_rect,
4};
5
6/// Pan + zoom the viewport so selected nodes fit the window (⌘⇧F / Ctrl⇧F). Undo restores prior view.
7pub struct FocusSelectionPlugin;
8
9impl FocusSelectionPlugin {
10    pub fn new() -> Self {
11        Self
12    }
13}
14
15fn focus_shortcut(ev: &gpui::KeyDownEvent) -> bool {
16    primary_platform_modifier(ev) && ev.keystroke.modifiers.shift
17}
18
19fn focus_selected(ctx: &mut PluginContext) {
20    let Some(bounds) = ctx.graph.selection_bounds() else {
21        return;
22    };
23    let bx: f32 = bounds.origin.x.into();
24    let by: f32 = bounds.origin.y.into();
25    let bw: f32 = bounds.size.width.into();
26    let bh: f32 = bounds.size.height.into();
27    frame_world_rect(ctx, bx, by, bw, bh);
28}
29
30pub(crate) fn focus_viewport_on_selection(ctx: &mut PluginContext) {
31    focus_selected(ctx);
32}
33
34impl Plugin for FocusSelectionPlugin {
35    fn name(&self) -> &'static str {
36        "focus_selection"
37    }
38
39    fn setup(&mut self, _ctx: &mut crate::plugin::InitPluginContext) {}
40
41    fn priority(&self) -> i32 {
42        90
43    }
44
45    fn on_event(
46        &mut self,
47        event: &FlowEvent,
48        ctx: &mut PluginContext,
49    ) -> crate::plugin::EventResult {
50        if let FlowEvent::Input(crate::plugin::InputEvent::KeyDown(ev)) = event {
51            if focus_shortcut(ev) && ev.keystroke.key == "f" {
52                focus_selected(ctx);
53                return crate::plugin::EventResult::Stop;
54            }
55        }
56        crate::plugin::EventResult::Continue
57    }
58}