dear_imgui_rs/widget/
text.rs

1//! Text helpers
2//!
3//! Convenience functions for colored text, wrapped text, disabled text and
4//! label helpers.
5//!
6//! Quick examples:
7//! ```no_run
8//! # use dear_imgui_rs::*;
9//! # let mut ctx = Context::create();
10//! # let ui = ctx.frame();
11//! ui.text("normal");
12//! ui.text_colored([1.0, 0.5, 0.0, 1.0], "warning");
13//! ui.text_disabled("disabled");
14//! ui.text_wrapped("very long text that will wrap when needed...");
15//! ```
16//!
17use crate::Ui;
18use crate::style::StyleColor;
19use crate::sys;
20
21impl Ui {
22    /// Display colored text
23    ///
24    /// This implementation uses zero-copy optimization with `igTextEx`,
25    /// avoiding string allocation and null-termination overhead.
26    ///
27    /// # Example
28    /// ```no_run
29    /// # use dear_imgui_rs::*;
30    /// # let mut ctx = Context::create();
31    /// # let ui = ctx.frame();
32    /// ui.text_colored([1.0, 0.0, 0.0, 1.0], "Red text");
33    /// ui.text_colored([0.0, 1.0, 0.0, 1.0], "Green text");
34    /// ```
35    #[doc(alias = "TextColored")]
36    pub fn text_colored(&self, color: [f32; 4], text: impl AsRef<str>) {
37        let s = text.as_ref();
38
39        // Temporarily set the text color
40        let _token = self.push_style_color(StyleColor::Text, color);
41
42        // Use igTextEx with zero-copy (begin/end pointers)
43        unsafe {
44            let begin = s.as_ptr() as *const std::os::raw::c_char;
45            let end = begin.add(s.len());
46            sys::igTextEx(begin, end, 0); // ImGuiTextFlags_None = 0
47        }
48    }
49
50    /// Display disabled (grayed out) text
51    ///
52    /// This implementation uses zero-copy optimization with `igTextEx`,
53    /// avoiding string allocation and null-termination overhead.
54    ///
55    /// # Example
56    /// ```no_run
57    /// # use dear_imgui_rs::*;
58    /// # let mut ctx = Context::create();
59    /// # let ui = ctx.frame();
60    /// ui.text_disabled("This option is not available");
61    /// ```
62    #[doc(alias = "TextDisabled")]
63    pub fn text_disabled(&self, text: impl AsRef<str>) {
64        let s = text.as_ref();
65
66        // Get the disabled color from the current style
67        let disabled_color = self.style_color(StyleColor::TextDisabled);
68
69        // Temporarily set the text color to disabled color
70        let _token = self.push_style_color(StyleColor::Text, disabled_color);
71
72        // Use igTextEx with zero-copy (begin/end pointers)
73        unsafe {
74            let begin = s.as_ptr() as *const std::os::raw::c_char;
75            let end = begin.add(s.len());
76            sys::igTextEx(begin, end, 0); // ImGuiTextFlags_None = 0
77        }
78    }
79
80    /// Display text wrapped to fit the current item width
81    ///
82    /// This uses `PushTextWrapPos + TextUnformatted + PopTextWrapPos` to avoid
83    /// calling C variadic APIs and to keep the input string unformatted.
84    #[doc(alias = "TextWrapped")]
85    pub fn text_wrapped(&self, text: impl AsRef<str>) {
86        let s = text.as_ref();
87        unsafe {
88            sys::igPushTextWrapPos(0.0);
89            let begin = s.as_ptr() as *const std::os::raw::c_char;
90            let end = begin.add(s.len());
91            sys::igTextUnformatted(begin, end);
92            sys::igPopTextWrapPos();
93        }
94    }
95
96    /// Display a label and text on the same line
97    #[doc(alias = "LabelText")]
98    pub fn label_text(&self, label: impl AsRef<str>, text: impl AsRef<str>) {
99        let (label_ptr, text_ptr) = self.scratch_txt_two(label, text);
100        unsafe {
101            // Always treat the value as unformatted user text.
102            const FMT: &[u8; 3] = b"%s\0";
103            sys::igLabelText(
104                label_ptr,
105                FMT.as_ptr() as *const std::os::raw::c_char,
106                text_ptr,
107            );
108        }
109    }
110
111    /// Render a hyperlink-style text button. Returns true when clicked.
112    #[doc(alias = "TextLink")]
113    pub fn text_link(&self, label: impl AsRef<str>) -> bool {
114        unsafe { sys::igTextLink(self.scratch_txt(label)) }
115    }
116
117    /// Render a hyperlink-style text button, and open the given URL when clicked.
118    /// Returns true when clicked.
119    #[doc(alias = "TextLinkOpenURL")]
120    pub fn text_link_open_url(&self, label: impl AsRef<str>, url: impl AsRef<str>) -> bool {
121        let (label_ptr, url_ptr) = self.scratch_txt_two(label, url);
122        unsafe { sys::igTextLinkOpenURL(label_ptr, url_ptr) }
123    }
124}