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(crate) 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}