Skip to main content

ccf_gpui_widgets/widgets/
path_display.rs

1//! Shared path display types for file and directory pickers
2//!
3//! This module contains common types and utilities used by both `FilePicker`
4//! and `DirectoryPicker` for displaying path information with color highlighting.
5
6#[cfg(feature = "file-picker")]
7use gpui::*;
8
9/// Controls how validation feedback is displayed in file/directory pickers
10#[derive(Clone, Debug, Default, PartialEq, Eq)]
11pub enum ValidationDisplay {
12    /// Show colored path segments and explanation message (default)
13    #[default]
14    Full,
15    /// Show colored path segments only, hide explanation message
16    ColorsOnly,
17    /// Show explanation message only, no path coloring
18    MessageOnly,
19    /// Hide all validation feedback (no colors, no message)
20    Hidden,
21}
22
23/// A single highlighted segment of a path display
24#[cfg(feature = "file-picker")]
25pub(crate) struct PathHighlight {
26    pub start: usize,
27    pub end: usize,
28    pub color: u32,
29}
30
31/// Path display information with styled segments and optional explanation
32#[cfg(feature = "file-picker")]
33pub(crate) struct PathDisplayInfo {
34    pub full_text: String,
35    pub highlights: Vec<PathHighlight>,
36    pub explanation: Option<(String, u32)>,
37}
38
39#[cfg(feature = "file-picker")]
40impl PathDisplayInfo {
41    /// Create a new empty path display info
42    pub fn new() -> Self {
43        Self {
44            full_text: String::new(),
45            highlights: Vec::new(),
46            explanation: None,
47        }
48    }
49
50    /// Add a segment of text with the given color
51    pub fn add_segment(&mut self, text: &str, color: u32) {
52        if !text.is_empty() {
53            let start = self.full_text.len();
54            self.full_text.push_str(text);
55            let end = self.full_text.len();
56            self.highlights.push(PathHighlight { start, end, color });
57        }
58    }
59
60    /// Add a segment with a leading path separator (/)
61    pub fn add_path_prefix(&mut self, text: &str, color: u32) {
62        let start = self.full_text.len();
63        self.full_text.push('/');
64        self.full_text.push_str(text);
65        let end = self.full_text.len();
66        self.highlights.push(PathHighlight { start, end, color });
67    }
68
69    /// Set the explanation message with color
70    pub fn set_explanation(&mut self, msg: &str, color: u32) {
71        self.explanation = Some((msg.to_string(), color));
72    }
73
74    /// Convert to a StyledText for rendering
75    pub fn to_styled_text(&self) -> StyledText {
76        let highlights: Vec<(std::ops::Range<usize>, HighlightStyle)> = self
77            .highlights
78            .iter()
79            .map(|h| (h.start..h.end, HighlightStyle::color(rgb(h.color).into())))
80            .collect();
81
82        StyledText::new(self.full_text.clone()).with_highlights(highlights)
83    }
84
85    /// Check if the display info is empty
86    pub fn is_empty(&self) -> bool {
87        self.full_text.is_empty()
88    }
89}
90
91#[cfg(feature = "file-picker")]
92impl Default for PathDisplayInfo {
93    fn default() -> Self {
94        Self::new()
95    }
96}