iced_code_editor/canvas_editor/
view.rs

1//! Iced UI view and rendering logic.
2
3use iced::widget::canvas::Canvas;
4use iced::widget::{Scrollable, container, scrollable};
5use iced::{Border, Color, Element, Length, Shadow};
6
7use super::{CodeEditor, LINE_HEIGHT, Message};
8
9impl CodeEditor {
10    /// Creates the view element with scrollable wrapper.
11    pub fn view(&self) -> Element<'_, Message> {
12        // Calculate total content height (minimum = viewport height)
13        let total_lines = self.buffer.line_count();
14        let content_height = total_lines as f32 * LINE_HEIGHT;
15        let min_height = content_height.max(self.viewport_height);
16
17        // Create canvas with fixed height based on content or viewport
18        let canvas = Canvas::new(self)
19            .width(Length::Fill)
20            .height(Length::Fixed(min_height));
21
22        // Capture style colors for the scrollbar style closure
23        let scrollbar_bg = self.style.scrollbar_background;
24        let scroller_color = self.style.scroller_color;
25
26        // Wrap in scrollable for automatic scrollbar display with custom style
27        Scrollable::new(canvas)
28            .id(self.scrollable_id.clone())
29            .width(Length::Fill)
30            .height(Length::Fill)
31            .on_scroll(Message::Scrolled)
32            .style(move |_theme, _status| scrollable::Style {
33                container: container::Style::default(),
34                vertical_rail: scrollable::Rail {
35                    background: Some(scrollbar_bg.into()),
36                    border: Border {
37                        radius: 4.0.into(),
38                        width: 0.0,
39                        color: Color::TRANSPARENT,
40                    },
41                    scroller: scrollable::Scroller {
42                        background: scroller_color.into(),
43                        border: Border {
44                            radius: 4.0.into(),
45                            width: 0.0,
46                            color: Color::TRANSPARENT,
47                        },
48                    },
49                },
50                horizontal_rail: scrollable::Rail {
51                    background: Some(scrollbar_bg.into()),
52                    border: Border {
53                        radius: 4.0.into(),
54                        width: 0.0,
55                        color: Color::TRANSPARENT,
56                    },
57                    scroller: scrollable::Scroller {
58                        background: scroller_color.into(),
59                        border: Border {
60                            radius: 4.0.into(),
61                            width: 0.0,
62                            color: Color::TRANSPARENT,
63                        },
64                    },
65                },
66                gap: None,
67                auto_scroll: scrollable::AutoScroll {
68                    background: Color::TRANSPARENT.into(),
69                    border: Border::default(),
70                    shadow: Shadow::default(),
71                    icon: Color::TRANSPARENT,
72                },
73            })
74            .into()
75    }
76}