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 based on actual lines only
13        let total_lines = self.buffer.line_count();
14        let content_height = total_lines as f32 * LINE_HEIGHT;
15
16        // Create canvas with height based on content only
17        // The scrollable wrapper will handle the viewport constraints
18        let canvas = Canvas::new(self)
19            .width(Length::Fill)
20            .height(Length::Fixed(content_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        // Use Length::Shrink to respect parent container constraints
28        Scrollable::new(canvas)
29            .id(self.scrollable_id.clone())
30            .width(Length::Fill)
31            .height(Length::Shrink)
32            .on_scroll(Message::Scrolled)
33            .style(move |_theme, _status| scrollable::Style {
34                container: container::Style::default(),
35                vertical_rail: scrollable::Rail {
36                    background: Some(scrollbar_bg.into()),
37                    border: Border {
38                        radius: 4.0.into(),
39                        width: 0.0,
40                        color: Color::TRANSPARENT,
41                    },
42                    scroller: scrollable::Scroller {
43                        background: scroller_color.into(),
44                        border: Border {
45                            radius: 4.0.into(),
46                            width: 0.0,
47                            color: Color::TRANSPARENT,
48                        },
49                    },
50                },
51                horizontal_rail: scrollable::Rail {
52                    background: Some(scrollbar_bg.into()),
53                    border: Border {
54                        radius: 4.0.into(),
55                        width: 0.0,
56                        color: Color::TRANSPARENT,
57                    },
58                    scroller: scrollable::Scroller {
59                        background: scroller_color.into(),
60                        border: Border {
61                            radius: 4.0.into(),
62                            width: 0.0,
63                            color: Color::TRANSPARENT,
64                        },
65                    },
66                },
67                gap: None,
68                auto_scroll: scrollable::AutoScroll {
69                    background: Color::TRANSPARENT.into(),
70                    border: Border::default(),
71                    shadow: Shadow::default(),
72                    icon: Color::TRANSPARENT,
73                },
74            })
75            .into()
76    }
77}