Merge pull request #2536 from meithecatte/editor-clipping

text_editor: Avoid rendering text outside the border
This commit is contained in:
Héctor Ramón 2024-08-12 03:07:36 +02:00 committed by GitHub
commit 6d6f354b42
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 44 additions and 34 deletions

View file

@ -1,4 +1,4 @@
use crate::{Point, Radians, Size, Vector}; use crate::{Padding, Point, Radians, Size, Vector};
/// An axis-aligned rectangle. /// An axis-aligned rectangle.
#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)] #[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
@ -220,12 +220,26 @@ impl Rectangle<f32> {
} }
/// Expands the [`Rectangle`] a given amount. /// Expands the [`Rectangle`] a given amount.
pub fn expand(self, amount: f32) -> Self { pub fn expand(self, padding: impl Into<Padding>) -> Self {
let padding = padding.into();
Self { Self {
x: self.x - amount, x: self.x - padding.left,
y: self.y - amount, y: self.y - padding.top,
width: self.width + amount * 2.0, width: self.width + padding.horizontal(),
height: self.height + amount * 2.0, height: self.height + padding.vertical(),
}
}
/// Shrinks the [`Rectangle`] a given amount.
pub fn shrink(self, padding: impl Into<Padding>) -> Self {
let padding = padding.into();
Self {
x: self.x + padding.left,
y: self.y + padding.top,
width: self.width - padding.horizontal(),
height: self.height - padding.vertical(),
} }
} }

View file

@ -1,7 +1,7 @@
use iced::highlighter; use iced::highlighter;
use iced::keyboard; use iced::keyboard;
use iced::widget::{ use iced::widget::{
button, column, container, horizontal_space, pick_list, row, text, self, button, column, container, horizontal_space, pick_list, row, text,
text_editor, tooltip, text_editor, tooltip,
}; };
use iced::{Center, Element, Fill, Font, Subscription, Task, Theme}; use iced::{Center, Element, Fill, Font, Subscription, Task, Theme};
@ -49,13 +49,16 @@ impl Editor {
is_loading: true, is_loading: true,
is_dirty: false, is_dirty: false,
}, },
Task::perform( Task::batch([
load_file(format!( Task::perform(
"{}/src/main.rs", load_file(format!(
env!("CARGO_MANIFEST_DIR") "{}/src/main.rs",
)), env!("CARGO_MANIFEST_DIR")
Message::FileOpened, )),
), Message::FileOpened,
),
widget::focus_next(),
]),
) )
} }

View file

@ -729,7 +729,7 @@ where
defaults: &renderer::Style, defaults: &renderer::Style,
layout: Layout<'_>, layout: Layout<'_>,
cursor: mouse::Cursor, cursor: mouse::Cursor,
viewport: &Rectangle, _viewport: &Rectangle,
) { ) {
let bounds = layout.bounds(); let bounds = layout.bounds();
@ -768,20 +768,14 @@ where
style.background, style.background,
); );
let position = bounds.position() let text_bounds = bounds.shrink(self.padding);
+ Vector::new(self.padding.left, self.padding.top);
if internal.editor.is_empty() { if internal.editor.is_empty() {
if let Some(placeholder) = self.placeholder.clone() { if let Some(placeholder) = self.placeholder.clone() {
renderer.fill_text( renderer.fill_text(
Text { Text {
content: placeholder.into_owned(), content: placeholder.into_owned(),
bounds: bounds.size() bounds: text_bounds.size(),
- Size::new(
self.padding.right,
self.padding.bottom,
),
size: self size: self
.text_size .text_size
.unwrap_or_else(|| renderer.default_size()), .unwrap_or_else(|| renderer.default_size()),
@ -791,24 +785,21 @@ where
vertical_alignment: alignment::Vertical::Top, vertical_alignment: alignment::Vertical::Top,
shaping: text::Shaping::Advanced, shaping: text::Shaping::Advanced,
}, },
position, text_bounds.position(),
style.placeholder, style.placeholder,
*viewport, text_bounds,
); );
} }
} else { } else {
renderer.fill_editor( renderer.fill_editor(
&internal.editor, &internal.editor,
position, text_bounds.position(),
defaults.text_color, defaults.text_color,
*viewport, text_bounds,
); );
} }
let translation = Vector::new( let translation = text_bounds.position() - Point::ORIGIN;
bounds.x + self.padding.left,
bounds.y + self.padding.top,
);
if let Some(focus) = state.focus.as_ref() { if let Some(focus) = state.focus.as_ref() {
match internal.editor.cursor() { match internal.editor.cursor() {
@ -826,11 +817,13 @@ where
), ),
); );
if let Some(clipped_cursor) = bounds.intersection(&cursor) { if let Some(clipped_cursor) =
text_bounds.intersection(&cursor)
{
renderer.fill_quad( renderer.fill_quad(
renderer::Quad { renderer::Quad {
bounds: Rectangle { bounds: Rectangle {
x: clipped_cursor.x.floor(), x: clipped_cursor.x,
y: clipped_cursor.y, y: clipped_cursor.y,
width: clipped_cursor.width, width: clipped_cursor.width,
height: clipped_cursor.height, height: clipped_cursor.height,
@ -843,7 +836,7 @@ where
} }
Cursor::Selection(ranges) => { Cursor::Selection(ranges) => {
for range in ranges.into_iter().filter_map(|range| { for range in ranges.into_iter().filter_map(|range| {
bounds.intersection(&(range + translation)) text_bounds.intersection(&(range + translation))
}) { }) {
renderer.fill_quad( renderer.fill_quad(
renderer::Quad { renderer::Quad {