-
Notifications
You must be signed in to change notification settings - Fork 569
Add RichTextBuilder #1520
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add RichTextBuilder #1520
Changes from 3 commits
5b5e437
5307bb5
9b29feb
ebe194f
de904ae
8e2d49b
aac35be
ccc5f78
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,193 @@ | ||||||||||||||||||||||
| // Copyright 2018 The Druid Authors. | ||||||||||||||||||||||
| // | ||||||||||||||||||||||
| // Licensed under the Apache License, Version 2.0 (the "License"); | ||||||||||||||||||||||
| // you may not use this file except in compliance with the License. | ||||||||||||||||||||||
| // You may obtain a copy of the License at | ||||||||||||||||||||||
| // | ||||||||||||||||||||||
| // http://www.apache.org/licenses/LICENSE-2.0 | ||||||||||||||||||||||
| // | ||||||||||||||||||||||
| // Unless required by applicable law or agreed to in writing, software | ||||||||||||||||||||||
| // distributed under the License is distributed on an "AS IS" BASIS, | ||||||||||||||||||||||
| // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||||||||||||||||||||||
| // See the License for the specific language governing permissions and | ||||||||||||||||||||||
| // limitations under the License. | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| //! Rich text with style spans. | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| use std::ops::{Range, RangeBounds}; | ||||||||||||||||||||||
| use std::sync::Arc; | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| use super::{Attribute, AttributeSpans, TextStorage}; | ||||||||||||||||||||||
| use crate::piet::{ | ||||||||||||||||||||||
| util, Color, FontFamily, FontStyle, FontWeight, PietTextLayoutBuilder, TextLayoutBuilder, | ||||||||||||||||||||||
| TextStorage as PietTextStorage, | ||||||||||||||||||||||
| }; | ||||||||||||||||||||||
| use crate::{ArcStr, Data, Env, FontDescriptor, KeyOrValue}; | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| /// Text with optional style spans. | ||||||||||||||||||||||
| #[derive(Debug, Clone, Data)] | ||||||||||||||||||||||
| pub struct RichText { | ||||||||||||||||||||||
| buffer: ArcStr, | ||||||||||||||||||||||
| attrs: Arc<AttributeSpans>, | ||||||||||||||||||||||
| } | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| impl RichText { | ||||||||||||||||||||||
| /// Create a new `RichText` object with the provided text. | ||||||||||||||||||||||
| pub fn new(buffer: ArcStr) -> Self { | ||||||||||||||||||||||
| RichText::new_with_attributes(buffer, Default::default()) | ||||||||||||||||||||||
| } | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| /// Create a new `RichText`, providing explicit attributes. | ||||||||||||||||||||||
| pub fn new_with_attributes(buffer: ArcStr, attributes: AttributeSpans) -> Self { | ||||||||||||||||||||||
| RichText { | ||||||||||||||||||||||
| buffer, | ||||||||||||||||||||||
| attrs: Arc::new(attributes), | ||||||||||||||||||||||
| } | ||||||||||||||||||||||
| } | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| /// Builder-style method for adding an [`Attribute`] to a range of text. | ||||||||||||||||||||||
| /// | ||||||||||||||||||||||
| /// [`Attribute`]: enum.Attribute.html | ||||||||||||||||||||||
| pub fn with_attribute(mut self, range: impl RangeBounds<usize>, attr: Attribute) -> Self { | ||||||||||||||||||||||
| self.add_attribute(range, attr); | ||||||||||||||||||||||
| self | ||||||||||||||||||||||
| } | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| /// The length of the buffer, in utf8 code units. | ||||||||||||||||||||||
| pub fn len(&self) -> usize { | ||||||||||||||||||||||
| self.buffer.len() | ||||||||||||||||||||||
| } | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| /// Returns `true` if the underlying buffer is empty. | ||||||||||||||||||||||
| pub fn is_empty(&self) -> bool { | ||||||||||||||||||||||
| self.buffer.is_empty() | ||||||||||||||||||||||
| } | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| /// Add an [`Attribute`] to the provided range of text. | ||||||||||||||||||||||
| /// | ||||||||||||||||||||||
| /// [`Attribute`]: enum.Attribute.html | ||||||||||||||||||||||
| pub fn add_attribute(&mut self, range: impl RangeBounds<usize>, attr: Attribute) { | ||||||||||||||||||||||
| let range = util::resolve_range(range, self.buffer.len()); | ||||||||||||||||||||||
| Arc::make_mut(&mut self.attrs).add(range, attr); | ||||||||||||||||||||||
| } | ||||||||||||||||||||||
| } | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| impl PietTextStorage for RichText { | ||||||||||||||||||||||
| fn as_str(&self) -> &str { | ||||||||||||||||||||||
| self.buffer.as_str() | ||||||||||||||||||||||
| } | ||||||||||||||||||||||
| } | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| impl TextStorage for RichText { | ||||||||||||||||||||||
| fn add_attributes( | ||||||||||||||||||||||
| &self, | ||||||||||||||||||||||
| mut builder: PietTextLayoutBuilder, | ||||||||||||||||||||||
| env: &Env, | ||||||||||||||||||||||
| ) -> PietTextLayoutBuilder { | ||||||||||||||||||||||
| for (range, attr) in self.attrs.to_piet_attrs(env) { | ||||||||||||||||||||||
| builder = builder.range_attribute(range, attr); | ||||||||||||||||||||||
| } | ||||||||||||||||||||||
| builder | ||||||||||||||||||||||
| } | ||||||||||||||||||||||
| } | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| /// A builder for [`RichText`]. | ||||||||||||||||||||||
| /// | ||||||||||||||||||||||
| /// # Example | ||||||||||||||||||||||
| /// ``` | ||||||||||||||||||||||
| /// # use druid::text::{RichTextBuilder, Attribute}; | ||||||||||||||||||||||
| /// let mut rich_text = RichTextBuilder::new(); | ||||||||||||||||||||||
| /// rich_text.push("Hello World").underline(true); | ||||||||||||||||||||||
| /// let rich_text = rich_text.build(); | ||||||||||||||||||||||
|
||||||||||||||||||||||
| /// # use druid::text::{RichTextBuilder, Attribute}; | |
| /// let mut rich_text = RichTextBuilder::new(); | |
| /// rich_text.push("Hello World").underline(true); | |
| /// let rich_text = rich_text.build(); | |
| /// # use druid::text::{Attribute, RichTextBuilder}; | |
| /// # use druid::FontWeight; | |
| /// let mut builder = RichTextBuilder::new(); | |
| /// builder.push("Hello "); | |
| /// builder.push("World!").weight(FontWeight::Bold); | |
| /// let rich_text = rich_text.build(); |
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| /// Add string to the end of text and `AttributesAdder` for the added string. | |
| /// Append a `&str` to the end of the text. | |
| /// | |
| /// This method returns a [`AttributesAddr`] that can be used to style the newly | |
| /// added string slice. |
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd give this a slightly more verbose name:
| /// Get the `AttributesAdder` for the range. | |
| pub fn range(&mut self, range: Range<usize>) -> AttributesAdder { | |
| /// Get an [`AttributesAdder`] for the given range. | |
| /// | |
| /// This can be used to modify styles for a given range after it has been added. | |
| pub fn add_attributes_for_range(&mut self, range: Range<usize>) -> AttributesAdder { |
Uh oh!
There was an error while loading. Please reload this page.