Skip to content

Commit

Permalink
Add wrapping strategy for text and text_editor widgets
Browse files Browse the repository at this point in the history
  • Loading branch information
nrjais committed Jul 2, 2024
1 parent 4687bf7 commit b5f7bd8
Show file tree
Hide file tree
Showing 16 changed files with 105 additions and 5 deletions.
3 changes: 2 additions & 1 deletion core/src/renderer/null.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ use crate::alignment;
use crate::image;
use crate::renderer::{self, Renderer};
use crate::svg;
use crate::text::{self, Text};
use crate::text::{self, Text, Wrapping};
use crate::{
Background, Color, Font, Pixels, Point, Radians, Rectangle, Size,
Transformation,
Expand Down Expand Up @@ -143,6 +143,7 @@ impl text::Editor for () {
&mut self,
_new_bounds: Size,
_new_font: Self::Font,
_new_wrapping: Wrapping,
_new_size: Pixels,
_new_line_height: text::LineHeight,
_new_highlighter: &mut impl text::Highlighter,
Expand Down
17 changes: 17 additions & 0 deletions core/src/text.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,23 @@ pub struct Text<Content = String, Font = crate::Font> {

/// The [`Shaping`] strategy of the [`Text`].
pub shaping: Shaping,

/// The [`Wrapping`] strategy of the [`Text`].
pub wrapping: Wrapping,
}

/// The wrapping strategy of some text.
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Default)]
pub enum Wrapping {
/// No wrapping.
None,
/// Word wrapping.
///
/// This is the default.
#[default]
Word,
/// Glyph wrapping.
Glyph,
}

/// The shaping strategy of some text.
Expand Down
3 changes: 2 additions & 1 deletion core/src/text/editor.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
//! Edit text.
use crate::text::highlighter::{self, Highlighter};
use crate::text::LineHeight;
use crate::text::{LineHeight, Wrapping};
use crate::{Pixels, Point, Rectangle, Size};

use std::sync::Arc;
Expand Down Expand Up @@ -45,6 +45,7 @@ pub trait Editor: Sized + Default {
&mut self,
new_bounds: Size,
new_font: Self::Font,
new_wrapping: Wrapping,
new_size: Pixels,
new_line_height: LineHeight,
new_highlighter: &mut impl Highlighter,
Expand Down
13 changes: 12 additions & 1 deletion core/src/widget/text.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ use crate::{

use std::borrow::Cow;

pub use text::{LineHeight, Shaping};
pub use text::{LineHeight, Shaping, Wrapping};

/// A paragraph of text.
#[allow(missing_debug_implementations)]
Expand All @@ -31,6 +31,7 @@ where
font: Option<Renderer::Font>,
shaping: Shaping,
class: Theme::Class<'a>,
wrapping: Wrapping,
}

impl<'a, Theme, Renderer> Text<'a, Theme, Renderer>
Expand All @@ -51,6 +52,7 @@ where
vertical_alignment: alignment::Vertical::Top,
shaping: Shaping::Basic,
class: Theme::default(),
wrapping: Default::default(),
}
}

Expand Down Expand Up @@ -110,6 +112,12 @@ where
self
}

/// Sets the [`Wrapping`] strategy of the [`Text`].
pub fn wrapping(mut self, wrapping: Wrapping) -> Self {
self.wrapping = wrapping;
self
}

/// Sets the style of the [`Text`].
#[must_use]
pub fn style(mut self, style: impl Fn(&Theme) -> Style + 'a) -> Self
Expand Down Expand Up @@ -191,6 +199,7 @@ where
self.horizontal_alignment,
self.vertical_alignment,
self.shaping,
self.wrapping,
)
}

Expand Down Expand Up @@ -225,6 +234,7 @@ pub fn layout<Renderer>(
horizontal_alignment: alignment::Horizontal,
vertical_alignment: alignment::Vertical,
shaping: Shaping,
wrapping: Wrapping,
) -> layout::Node
where
Renderer: text::Renderer,
Expand All @@ -246,6 +256,7 @@ where
horizontal_alignment,
vertical_alignment,
shaping,
wrapping,
});

paragraph.min_bounds()
Expand Down
20 changes: 18 additions & 2 deletions examples/editor/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,11 @@ use iced::highlighter::{self, Highlighter};
use iced::keyboard;
use iced::widget::{
button, column, container, horizontal_space, pick_list, row, text,
text_editor, tooltip,
text_editor, toggler, tooltip,
};
use iced::{Alignment, Element, Font, Length, Subscription, Task, Theme};

use iced::widget::text::Wrapping;
use std::ffi;
use std::io;
use std::path::{Path, PathBuf};
Expand All @@ -27,6 +28,7 @@ struct Editor {
theme: highlighter::Theme,
is_loading: bool,
is_dirty: bool,
wrap: bool,
}

#[derive(Debug, Clone)]
Expand All @@ -38,6 +40,7 @@ enum Message {
FileOpened(Result<(PathBuf, Arc<String>), Error>),
SaveFile,
FileSaved(Result<PathBuf, Error>),
ToggleWrap(bool),
}

impl Editor {
Expand All @@ -48,6 +51,7 @@ impl Editor {
theme: highlighter::Theme::SolarizedDark,
is_loading: true,
is_dirty: false,
wrap: true,
}
}

Expand Down Expand Up @@ -122,6 +126,10 @@ impl Editor {

Task::none()
}
Message::ToggleWrap(enabled) => {
self.wrap = enabled;
Command::none()
}
}
}

Expand All @@ -148,13 +156,16 @@ impl Editor {
self.is_dirty.then_some(Message::SaveFile)
),
horizontal_space(),
toggler("Word wrap".to_string(), self.wrap, Message::ToggleWrap)
.text_size(14)
.width(Length::Shrink),
pick_list(
highlighter::Theme::ALL,
Some(self.theme),
Message::ThemeSelected
)
.text_size(14)
.padding([5, 10])
.padding([5, 10]),
]
.spacing(10)
.align_items(Alignment::Center);
Expand Down Expand Up @@ -184,6 +195,11 @@ impl Editor {
controls,
text_editor(&self.content)
.height(Length::Fill)
.wrapping(if self.wrap {
Wrapping::Word
} else {
Wrapping::None
})
.on_action(Message::ActionPerformed)
.highlight::<Highlighter>(
highlighter::Settings {
Expand Down
9 changes: 9 additions & 0 deletions graphics/src/text.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ use crate::core::font::{self, Font};
use crate::core::text::Shaping;
use crate::core::{Color, Pixels, Point, Rectangle, Size, Transformation};

use iced_core::text::Wrapping;
use once_cell::sync::OnceCell;
use std::borrow::Cow;
use std::sync::{Arc, RwLock, Weak};
Expand Down Expand Up @@ -250,6 +251,14 @@ pub fn to_attributes(font: Font) -> cosmic_text::Attrs<'static> {
.style(to_style(font.style))
}

fn to_wrap(wrapping: Wrapping) -> cosmic_text::Wrap {
match wrapping {
Wrapping::None => cosmic_text::Wrap::None,
Wrapping::Word => cosmic_text::Wrap::Word,
Wrapping::Glyph => cosmic_text::Wrap::Glyph,
}
}

fn to_family(family: font::Family) -> cosmic_text::Family<'static> {
match family {
font::Family::Name(name) => cosmic_text::Family::Name(name),
Expand Down
11 changes: 11 additions & 0 deletions graphics/src/text/editor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ use crate::text;

use cosmic_text::Edit as _;

use crate::text::to_wrap;
use std::fmt;
use std::sync::{self, Arc};

Expand Down Expand Up @@ -480,6 +481,7 @@ impl editor::Editor for Editor {
&mut self,
new_bounds: Size,
new_font: Font,
new_wrapping: text::Wrapping,
new_size: Pixels,
new_line_height: LineHeight,
new_highlighter: &mut impl Highlighter,
Expand Down Expand Up @@ -531,6 +533,15 @@ impl editor::Editor for Editor {
);
}

let new_wrap = to_wrap(new_wrapping);
if new_wrap != internal.editor.buffer().wrap() {
log::trace!("Updating wrapping strategy of `Editor`...");
internal
.editor
.buffer_mut()
.set_wrap(font_system.raw(), new_wrap);
}

if new_bounds != internal.bounds {
log::trace!("Updating size of `Editor`...");

Expand Down
10 changes: 10 additions & 0 deletions graphics/src/text/paragraph.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ use crate::core::text::{Hit, LineHeight, Shaping, Text};
use crate::core::{Font, Pixels, Point, Size};
use crate::text;

use iced_core::text::Wrapping;
use std::fmt;
use std::sync::{self, Arc};

Expand All @@ -22,6 +23,7 @@ struct Internal {
bounds: Size,
min_bounds: Size,
version: text::Version,
wrapping: Wrapping,
}

impl Paragraph {
Expand Down Expand Up @@ -88,6 +90,8 @@ impl core::text::Paragraph for Paragraph {
text::to_shaping(text.shaping),
);

buffer.set_wrap(font_system.raw(), text::to_wrap(text.wrapping));

let min_bounds = text::measure(&buffer);

Self(Some(Arc::new(Internal {
Expand All @@ -100,6 +104,7 @@ impl core::text::Paragraph for Paragraph {
bounds: text.bounds,
min_bounds,
version: font_system.version(),
wrapping: text.wrapping,
})))
}

Expand Down Expand Up @@ -141,6 +146,7 @@ impl core::text::Paragraph for Paragraph {
horizontal_alignment: internal.horizontal_alignment,
vertical_alignment: internal.vertical_alignment,
shaping: internal.shaping,
wrapping: internal.wrapping,
});
}
}
Expand All @@ -159,6 +165,7 @@ impl core::text::Paragraph for Paragraph {
|| paragraph.shaping != text.shaping
|| paragraph.horizontal_alignment != text.horizontal_alignment
|| paragraph.vertical_alignment != text.vertical_alignment
|| paragraph.wrapping != text.wrapping
{
core::text::Difference::Shape
} else if paragraph.bounds != text.bounds {
Expand Down Expand Up @@ -247,6 +254,7 @@ impl fmt::Debug for Paragraph {
.field("vertical_alignment", &paragraph.vertical_alignment)
.field("bounds", &paragraph.bounds)
.field("min_bounds", &paragraph.min_bounds)
.field("wrapping", &paragraph.wrapping)
.finish()
}
}
Expand All @@ -261,6 +269,7 @@ impl PartialEq for Internal {
&& self.bounds == other.bounds
&& self.min_bounds == other.min_bounds
&& self.buffer.metrics() == other.buffer.metrics()
&& self.wrapping == other.wrapping
}
}

Expand All @@ -279,6 +288,7 @@ impl Default for Internal {
bounds: Size::ZERO,
min_bounds: Size::ZERO,
version: text::Version::default(),
wrapping: Wrapping::default(),
}
}
}
Expand Down
1 change: 1 addition & 0 deletions wgpu/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -408,6 +408,7 @@ impl Renderer {
horizontal_alignment: alignment::Horizontal::Left,
vertical_alignment: alignment::Vertical::Top,
shaping: core::text::Shaping::Basic,
wrapping: core::text::Wrapping::default(),
};

renderer.fill_text(
Expand Down
3 changes: 3 additions & 0 deletions widget/src/checkbox.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ use crate::core::layout;
use crate::core::mouse;
use crate::core::renderer;
use crate::core::text;
use crate::core::text::Wrapping;
use crate::core::theme::palette;
use crate::core::touch;
use crate::core::widget;
Expand Down Expand Up @@ -240,6 +241,7 @@ where
alignment::Horizontal::Left,
alignment::Vertical::Top,
self.text_shaping,
Wrapping::default(),
)
},
)
Expand Down Expand Up @@ -348,6 +350,7 @@ where
horizontal_alignment: alignment::Horizontal::Center,
vertical_alignment: alignment::Vertical::Center,
shaping: *shaping,
wrapping: Wrapping::default(),
},
bounds.center(),
style.icon_color,
Expand Down
1 change: 1 addition & 0 deletions widget/src/overlay/menu.rs
Original file line number Diff line number Diff line change
Expand Up @@ -534,6 +534,7 @@ where
horizontal_alignment: alignment::Horizontal::Left,
vertical_alignment: alignment::Vertical::Center,
shaping: self.text_shaping,
wrapping: text::Wrapping::default(),
},
Point::new(bounds.x + self.padding.left, bounds.center_y()),
if is_selected {
Expand Down
3 changes: 3 additions & 0 deletions widget/src/pick_list.rs
Original file line number Diff line number Diff line change
Expand Up @@ -249,6 +249,7 @@ where
horizontal_alignment: alignment::Horizontal::Left,
vertical_alignment: alignment::Vertical::Center,
shaping: self.text_shaping,
wrapping: text::Wrapping::default(),
};

for (option, paragraph) in options.iter().zip(state.options.iter_mut())
Expand Down Expand Up @@ -514,6 +515,7 @@ where
horizontal_alignment: alignment::Horizontal::Right,
vertical_alignment: alignment::Vertical::Center,
shaping,
wrapping: text::Wrapping::default(),
},
Point::new(
bounds.x + bounds.width - self.padding.right,
Expand Down Expand Up @@ -543,6 +545,7 @@ where
horizontal_alignment: alignment::Horizontal::Left,
vertical_alignment: alignment::Vertical::Center,
shaping: self.text_shaping,
wrapping: text::Wrapping::default(),
},
Point::new(bounds.x + self.padding.left, bounds.center_y()),
if is_selected {
Expand Down
1 change: 1 addition & 0 deletions widget/src/radio.rs
Original file line number Diff line number Diff line change
Expand Up @@ -244,6 +244,7 @@ where
alignment::Horizontal::Left,
alignment::Vertical::Top,
self.text_shaping,
text::Wrapping::default(),
)
},
)
Expand Down
Loading

0 comments on commit b5f7bd8

Please sign in to comment.