boxmux_lib/components/text_content.rs
1use crate::components::renderable_content::{
2 ContentEvent, EventResult, EventType, HoverState, RenderableContent, SensitiveZone,
3};
4use crate::draw_utils::content_size;
5
6/// TextContent implementation of RenderableContent trait
7/// Preserves all existing text rendering logic from draw_utils.rs
8pub struct TextContent<'a> {
9 /// The raw text content to render
10 text: &'a str,
11 /// Text foreground color
12 _fg_color: &'a Option<String>,
13 /// Text background color
14 _bg_color: &'a Option<String>,
15}
16
17impl<'a> TextContent<'a> {
18 /// Create new TextContent
19 pub fn new(text: &'a str, fg_color: &'a Option<String>, bg_color: &'a Option<String>) -> Self {
20 Self {
21 text,
22 _fg_color: fg_color,
23 _bg_color: bg_color,
24 }
25 }
26
27 /// Calculate content dimensions using existing logic
28 fn calculate_dimensions(&self) -> (usize, usize) {
29 content_size(self.text)
30 }
31}
32
33impl<'a> RenderableContent for TextContent<'a> {
34 /// Get raw content dimensions using existing content_size logic
35 fn get_dimensions(&self) -> (usize, usize) {
36 self.calculate_dimensions()
37 }
38
39 /// Get raw content string
40 fn get_raw_content(&self) -> String {
41 self.text.to_string()
42 }
43
44 /// Get box-relative sensitive zones
45 fn get_box_relative_sensitive_zones(&self) -> Vec<SensitiveZone> {
46 Vec::new() // Text content typically doesn't have sensitive zones
47 }
48
49 /// Handle content events on text
50 fn handle_event(&mut self, event: &ContentEvent) -> EventResult {
51 match event.event_type {
52 EventType::Click => {
53 // Text content generally doesn't handle clicks unless it has links
54 EventResult::NotHandled
55 }
56 EventType::KeyPress => {
57 // Text could handle copy operations, search, etc.
58 if let Some(key_info) = event.key_info() {
59 match key_info.key.as_str() {
60 "c" if key_info.modifiers.contains(
61 &crate::components::renderable_content::KeyModifier::Ctrl,
62 ) =>
63 {
64 // Ctrl+C for copy - could be handled here or at higher level
65 EventResult::NotHandled
66 }
67 "/" | "f"
68 if key_info.modifiers.contains(
69 &crate::components::renderable_content::KeyModifier::Ctrl,
70 ) =>
71 {
72 // Search functionality
73 EventResult::NotHandled
74 }
75 _ => EventResult::NotHandled,
76 }
77 } else {
78 EventResult::NotHandled
79 }
80 }
81 EventType::Scroll => {
82 // Scroll events could be handled for text navigation
83 EventResult::HandledContinue // Let scrollbars handle but continue propagation
84 }
85 EventType::MouseMove => {
86 // Handle mouse movement over text for cursor changes, selection
87 if let Some(mouse_move) = event.mouse_move_info() {
88 if mouse_move.is_dragging {
89 // Text selection via drag
90 EventResult::NotHandled // Could be handled for text selection
91 } else {
92 // Normal movement - change cursor, show position
93 EventResult::NotHandled
94 }
95 } else {
96 EventResult::NotHandled
97 }
98 }
99 EventType::Hover => {
100 // Handle hover over text for tooltips, word highlighting
101 if let Some(hover_info) = event.hover_info() {
102 match hover_info.state {
103 HoverState::Enter | HoverState::Move => {
104 // Could show word definitions, tooltips
105 EventResult::NotHandled
106 }
107 HoverState::Leave => {
108 // Hide tooltips
109 EventResult::NotHandled
110 }
111 }
112 } else {
113 EventResult::NotHandled
114 }
115 }
116 EventType::BoxResize => {
117 // Text content needs to reflow on resize
118 EventResult::StateChanged // Trigger re-render with new dimensions
119 }
120 EventType::TitleChange => {
121 // Text content doesn't typically handle title changes
122 EventResult::NotHandled
123 }
124 _ => EventResult::NotHandled,
125 }
126 }
127}