summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLibravatar Héctor Ramón <hector@hecrj.dev>2024-08-12 03:07:36 +0200
committerLibravatar GitHub <noreply@github.com>2024-08-12 03:07:36 +0200
commit6d6f354b425def8b4ab269cdd22cfb2328ce8591 (patch)
treeb02e2f09733454b0c7917ae238824bb4b318a00e
parent1c8850023f2bdeae02ec061a49aa76dbb91262ad (diff)
parent3e59d824f8be029720f4064b49099e6aabc11179 (diff)
downloadiced-6d6f354b425def8b4ab269cdd22cfb2328ce8591.tar.gz
iced-6d6f354b425def8b4ab269cdd22cfb2328ce8591.tar.bz2
iced-6d6f354b425def8b4ab269cdd22cfb2328ce8591.zip
Merge pull request #2536 from meithecatte/editor-clipping
text_editor: Avoid rendering text outside the border
-rw-r--r--core/src/rectangle.rs26
-rw-r--r--examples/editor/src/main.rs19
-rw-r--r--widget/src/text_editor.rs33
3 files changed, 44 insertions, 34 deletions
diff --git a/core/src/rectangle.rs b/core/src/rectangle.rs
index 99c8d55d..cff33991 100644
--- a/core/src/rectangle.rs
+++ b/core/src/rectangle.rs
@@ -1,4 +1,4 @@
-use crate::{Point, Radians, Size, Vector};
+use crate::{Padding, Point, Radians, Size, Vector};
/// An axis-aligned rectangle.
#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
@@ -220,12 +220,26 @@ impl Rectangle<f32> {
}
/// 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 {
+ x: self.x - padding.left,
+ y: self.y - padding.top,
+ width: self.width + padding.horizontal(),
+ 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 - amount,
- y: self.y - amount,
- width: self.width + amount * 2.0,
- height: self.height + amount * 2.0,
+ x: self.x + padding.left,
+ y: self.y + padding.top,
+ width: self.width - padding.horizontal(),
+ height: self.height - padding.vertical(),
}
}
diff --git a/examples/editor/src/main.rs b/examples/editor/src/main.rs
index 155e74a1..aa07b328 100644
--- a/examples/editor/src/main.rs
+++ b/examples/editor/src/main.rs
@@ -1,7 +1,7 @@
use iced::highlighter;
use iced::keyboard;
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,
};
use iced::{Center, Element, Fill, Font, Subscription, Task, Theme};
@@ -49,13 +49,16 @@ impl Editor {
is_loading: true,
is_dirty: false,
},
- Task::perform(
- load_file(format!(
- "{}/src/main.rs",
- env!("CARGO_MANIFEST_DIR")
- )),
- Message::FileOpened,
- ),
+ Task::batch([
+ Task::perform(
+ load_file(format!(
+ "{}/src/main.rs",
+ env!("CARGO_MANIFEST_DIR")
+ )),
+ Message::FileOpened,
+ ),
+ widget::focus_next(),
+ ]),
)
}
diff --git a/widget/src/text_editor.rs b/widget/src/text_editor.rs
index aac47b2d..85332ba4 100644
--- a/widget/src/text_editor.rs
+++ b/widget/src/text_editor.rs
@@ -729,7 +729,7 @@ where
defaults: &renderer::Style,
layout: Layout<'_>,
cursor: mouse::Cursor,
- viewport: &Rectangle,
+ _viewport: &Rectangle,
) {
let bounds = layout.bounds();
@@ -768,20 +768,14 @@ where
style.background,
);
- let position = bounds.position()
- + Vector::new(self.padding.left, self.padding.top);
+ let text_bounds = bounds.shrink(self.padding);
if internal.editor.is_empty() {
if let Some(placeholder) = self.placeholder.clone() {
renderer.fill_text(
Text {
content: placeholder.into_owned(),
- bounds: bounds.size()
- - Size::new(
- self.padding.right,
- self.padding.bottom,
- ),
-
+ bounds: text_bounds.size(),
size: self
.text_size
.unwrap_or_else(|| renderer.default_size()),
@@ -791,24 +785,21 @@ where
vertical_alignment: alignment::Vertical::Top,
shaping: text::Shaping::Advanced,
},
- position,
+ text_bounds.position(),
style.placeholder,
- *viewport,
+ text_bounds,
);
}
} else {
renderer.fill_editor(
&internal.editor,
- position,
+ text_bounds.position(),
defaults.text_color,
- *viewport,
+ text_bounds,
);
}
- let translation = Vector::new(
- bounds.x + self.padding.left,
- bounds.y + self.padding.top,
- );
+ let translation = text_bounds.position() - Point::ORIGIN;
if let Some(focus) = state.focus.as_ref() {
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::Quad {
bounds: Rectangle {
- x: clipped_cursor.x.floor(),
+ x: clipped_cursor.x,
y: clipped_cursor.y,
width: clipped_cursor.width,
height: clipped_cursor.height,
@@ -843,7 +836,7 @@ where
}
Cursor::Selection(ranges) => {
for range in ranges.into_iter().filter_map(|range| {
- bounds.intersection(&(range + translation))
+ text_bounds.intersection(&(range + translation))
}) {
renderer.fill_quad(
renderer::Quad {