1
//! CSS properties for styling text selections (`-azul-selection-*`).
2
//!
3
//! Defines the following properties (analogous to the `::selection` pseudo-element):
4
//!
5
//! - `-azul-selection-background-color` ([`SelectionBackgroundColor`])
6
//! - `-azul-selection-color` ([`SelectionColor`])
7
//! - `-azul-selection-radius` ([`SelectionRadius`])
8

            
9
use alloc::string::String;
10

            
11
use crate::props::{
12
    basic::color::{parse_css_color, ColorU, CssColorParseError, CssColorParseErrorOwned},
13
    formatter::PrintAsCssValue,
14
};
15

            
16
/// Default selection highlight background — light blue, similar to macOS.
17
const DEFAULT_SELECTION_BG: ColorU = ColorU::new(173, 214, 255, 255);
18

            
19
// --- -azul-selection-background-color ---
20

            
21
/// Parsed value for the `-azul-selection-background-color` CSS property.
22
#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
23
#[repr(C)]
24
pub struct SelectionBackgroundColor {
25
    pub inner: ColorU,
26
}
27

            
28
impl Default for SelectionBackgroundColor {
29
    fn default() -> Self {
30
        Self {
31
            inner: DEFAULT_SELECTION_BG,
32
        }
33
    }
34
}
35

            
36
impl PrintAsCssValue for SelectionBackgroundColor {
37
    fn print_as_css_value(&self) -> String {
38
        self.inner.to_hash()
39
    }
40
}
41

            
42
impl crate::format_rust_code::FormatAsRustCode for SelectionBackgroundColor {
43
    fn format_as_rust_code(&self, _tabs: usize) -> String {
44
        format!(
45
            "SelectionBackgroundColor {{ inner: {} }}",
46
            crate::format_rust_code::format_color_value(&self.inner)
47
        )
48
    }
49
}
50

            
51
/// Parses a `-azul-selection-background-color` CSS value.
52
#[cfg(feature = "parser")]
53
pub fn parse_selection_background_color(
54
    input: &str,
55
) -> Result<SelectionBackgroundColor, CssColorParseError<'_>> {
56
    parse_css_color(input).map(|inner| SelectionBackgroundColor { inner })
57
}
58

            
59
// --- -azul-selection-color ---
60

            
61
/// Parsed value for the `-azul-selection-color` CSS property.
62
#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
63
#[repr(C)]
64
pub struct SelectionColor {
65
    pub inner: ColorU,
66
}
67

            
68
impl Default for SelectionColor {
69
    fn default() -> Self {
70
        Self {
71
            inner: ColorU::BLACK,
72
        }
73
    }
74
}
75

            
76
impl PrintAsCssValue for SelectionColor {
77
    fn print_as_css_value(&self) -> String {
78
        self.inner.to_hash()
79
    }
80
}
81

            
82
impl crate::format_rust_code::FormatAsRustCode for SelectionColor {
83
    fn format_as_rust_code(&self, _tabs: usize) -> String {
84
        format!(
85
            "SelectionColor {{ inner: {} }}",
86
            crate::format_rust_code::format_color_value(&self.inner)
87
        )
88
    }
89
}
90

            
91
/// Parses a `-azul-selection-color` CSS value.
92
#[cfg(feature = "parser")]
93
pub fn parse_selection_color(input: &str) -> Result<SelectionColor, CssColorParseError<'_>> {
94
    parse_css_color(input).map(|inner| SelectionColor { inner })
95
}
96

            
97
// --- -azul-selection-radius ---
98

            
99
use crate::props::basic::{
100
    pixel::{parse_pixel_value, CssPixelValueParseError, CssPixelValueParseErrorOwned, PixelValue},
101
    SizeMetric,
102
};
103

            
104
/// Parsed value for the `-azul-selection-radius` CSS property.
105
#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
106
#[repr(C)]
107
pub struct SelectionRadius {
108
    pub inner: PixelValue,
109
}
110

            
111
impl Default for SelectionRadius {
112
    fn default() -> Self {
113
        Self {
114
            inner: PixelValue::zero(),
115
        }
116
    }
117
}
118

            
119
impl PrintAsCssValue for SelectionRadius {
120
    fn print_as_css_value(&self) -> String {
121
        self.inner.to_string()
122
    }
123
}
124

            
125
impl crate::format_rust_code::FormatAsRustCode for SelectionRadius {
126
    fn format_as_rust_code(&self, _tabs: usize) -> String {
127
        // Use the Display implementation of PixelValue to get a string like "5px" or "1em"
128
        format!(
129
            "SelectionRadius {{ inner: PixelValue::from_metric(SizeMetric::{:?}, {}) }}",
130
            self.inner.metric,
131
            self.inner.number.get()
132
        )
133
    }
134
}
135

            
136
/// Parses a `-azul-selection-radius` CSS value.
137
#[cfg(feature = "parser")]
138
pub fn parse_selection_radius(input: &str) -> Result<SelectionRadius, CssPixelValueParseError<'_>> {
139
    parse_pixel_value(input).map(|inner| SelectionRadius { inner })
140
}