Skip to main content

stakpak_tui/
lib.rs

1// TUI crate performs heavy string slicing for text rendering, markdown parsing,
2// cursor positioning, and layout. All indices come from find()/rfind()/char_indices()
3// on the same strings. Allowing at crate level to avoid 120+ individual annotations.
4#![allow(clippy::string_slice)]
5
6mod app;
7mod constants;
8mod event;
9mod event_loop;
10mod terminal;
11mod view;
12pub use app::{
13    AppState, ExistingPlanPrompt, InputEvent, LoadingOperation, OutputEvent, SessionInfo,
14};
15pub use event_loop::{RulebookConfig, run_tui};
16pub use ratatui::style::Color;
17pub use services::banner::{BannerMessage, BannerStyle};
18
19pub mod services;
20
21use crossterm::event::{DisableMouseCapture, EnableMouseCapture};
22use crossterm::execute;
23pub use event::map_crossterm_event_to_input_event;
24use ratatui::style::Style;
25use std::io;
26pub use terminal::TerminalGuard;
27pub use view::view;
28
29use crate::services::detect_term::ThemeColors;
30use crate::services::message::{Message, invalidate_message_lines_cache};
31
32pub fn toggle_mouse_capture(state: &mut AppState) -> io::Result<()> {
33    state.terminal_ui_state.mouse_capture_enabled = !state.terminal_ui_state.mouse_capture_enabled;
34
35    if state.terminal_ui_state.mouse_capture_enabled {
36        execute!(std::io::stdout(), EnableMouseCapture)?;
37    } else {
38        execute!(std::io::stdout(), DisableMouseCapture)?;
39    }
40
41    let status = if state.terminal_ui_state.mouse_capture_enabled {
42        "enabled"
43    } else {
44        "disabled . Ctrl+L to enable"
45    };
46
47    let color = if state.terminal_ui_state.mouse_capture_enabled {
48        ThemeColors::green()
49    } else {
50        ThemeColors::red()
51    };
52    state
53        .messages_scrolling_state
54        .messages
55        .push(Message::info("SPACING_MARKER", None));
56    state.messages_scrolling_state.messages.push(Message::info(
57        format!("Mouse capture {}", status),
58        Some(Style::default().fg(color)),
59    ));
60    state
61        .messages_scrolling_state
62        .messages
63        .push(Message::info("SPACING_MARKER", None));
64
65    // Invalidate cache so the new messages are rendered
66    invalidate_message_lines_cache(state);
67
68    Ok(())
69}