Skip to main content

oo_ide/
views.rs

1pub(crate) mod command_runner;
2pub(crate) mod commit;
3pub mod editor;
4pub(crate) mod project_search;
5pub(crate) mod save_state;
6pub(crate) mod extension_config;
7pub mod file_selector;
8pub(crate) mod git_history;
9pub(crate) mod issue_view;
10pub(crate) mod log_view;
11// legacy SearchReplace view removed — editor now hosts expanded project search
12pub(crate) mod task_archive;
13pub mod terminal;
14
15use ratatui::{Frame, layout::Rect};
16
17use crate::input;
18use crate::operation::{Event, Operation};
19use crate::theme::Theme;
20use crate::settings::Settings;
21
22/// Whether a view is a primary working context or a temporary overlay.
23///
24/// - **Primary** views (Editor, Terminal, CommitWindow, GitHistory) represent the
25///   user's main working context. When opening a modal the current primary is
26///   stashed so it can be restored when the modal closes.
27/// - **Modal** views (FileSelector, CommandRunner, LogView, SearchReplace,
28///   ExtensionConfig) are overlays. Pressing `Esc` while in a modal view returns
29///   to the stashed primary view.
30#[derive(Debug, Clone, Copy, PartialEq, Eq)]
31pub enum ViewKind {
32    Primary,
33    Modal,
34}
35
36/// Every full-screen view implements this trait.
37///
38/// # Responsibilities
39///
40/// - `handle_key`       — translate raw input into operations (no mutation)
41/// - `handle_mouse`     — translate mouse events into operations (default no-op)
42/// - `handle_operation` — apply operations the view owns; emit an event on success
43/// - `render`           — draw the current state to the terminal frame
44///
45/// Views own their slice of state.  Nobody mutates a view's internals except
46/// the view itself, through `handle_operation`.
47pub trait View {
48    /// The kind of this view: [`ViewKind::Primary`] or [`ViewKind::Modal`].
49    ///
50    /// Used by the escape logic to decide whether to revert to the last primary
51    /// view or to ignore the key press.
52    const KIND: ViewKind;
53    /// Translate a key event into zero or more operations.
54    /// Must not mutate `self` — use `handle_operation` for that.
55    fn handle_key(&self, key: input::KeyEvent) -> Vec<Operation>;
56
57    /// Translate a mouse event into zero or more operations.
58    /// Default implementation is a no-op; views that support mouse override this.
59    fn handle_mouse(&self, _mouse: input::MouseEvent) -> Vec<Operation> {
60        vec![]
61    }
62
63    /// Apply a single operation if it is relevant to this view.
64    ///
65    /// Returns `Some(event)` if the operation was applied (so the event loop
66    /// can broadcast the resulting event to subscribers), or `None` if this
67    /// view does not own the operation.
68    fn handle_operation(&mut self, op: &Operation, settings: &Settings) -> Option<Event>;
69
70    /// Save the current state of the view before it is closed.
71    fn save_state(&mut self, app_state: &mut crate::app_state::AppState);
72
73    /// Draw the view into the provided `area` of the current frame.
74    fn render(&self, frame: &mut Frame, area: Rect, theme: &Theme);
75
76    /// Populate the global status bar with view-specific content.
77    ///
78    /// The default implementation is a no-op; views that want to surface
79    /// information in the status bar override this.
80    fn status_bar(&self, _state: &crate::app_state::AppState, _bar: &mut crate::widgets::status_bar::StatusBarBuilder) {}
81}