Skip to content

Commit

Permalink
refactor(widgets): 💡 Refactor Input Widget
Browse files Browse the repository at this point in the history
  • Loading branch information
wjian23 committed Dec 27, 2024
1 parent a0f025f commit 7954222
Show file tree
Hide file tree
Showing 23 changed files with 892 additions and 944 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ Please only add new entries below the [Unreleased](#unreleased---releasedate) he

- **core**: Refactor TextStyleWidget to support the setting of some font style fields. (#pr @wjian23)
- **core**: Rename `can_focus` field of FocusScope to `skip_host`. (#pr @wjian23)
- **widgets**: Refactor `Input` Widget. (#pr @wjian23)


## [0.4.0-alpha.20] - 2024-12-25
Expand Down
9 changes: 9 additions & 0 deletions core/src/state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,15 @@ pub trait StateWatcher: StateReader {
fn clone_watcher(&self) -> Watcher<Self::Reader> {
Watcher::new(self.clone_reader(), self.raw_modifies())
}

/// Return a new watcher by applying a function to the contained value.
fn map_watcher<V: ?Sized, M>(&self, part_map: M) -> Watcher<MapReader<Self::Reader, M>>
where
M: Fn(&Self::Value) -> PartData<V> + Clone,
{
let reader = self.map_reader(part_map);
Watcher::new(reader, self.raw_modifies())
}
}

pub trait StateWriter: StateWatcher {
Expand Down
2 changes: 1 addition & 1 deletion docs/en/practice_todos_app/develop_a_todos_app.md
Original file line number Diff line number Diff line change
Expand Up @@ -589,7 +589,7 @@ impl Compose for Todos {
$input.write().set_text("");
}
},
@{ Placeholder::new("What do you want to do ?") }
@Text { text:"What do you want to do ?" }
}
}
@Tabs {
Expand Down
2 changes: 1 addition & 1 deletion docs/zh/practice_todos_app/develop_a_todos_app.md
Original file line number Diff line number Diff line change
Expand Up @@ -592,7 +592,7 @@ impl Compose for Todos {
$input.write().set_text("");
}
},
@{ Placeholder::new("What do you want to do ?") }
@Text { text: "What do you want to do ?" }
}
}
@Tabs {
Expand Down
2 changes: 1 addition & 1 deletion examples/todos/src/ui.rs
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,7 @@ fn input(
$input.write().set_text("");
}
},
@{ Placeholder::new("What do you want to do ?") }
@Text { text: "What do you want to do ?" }
}
}
.into_widget()
Expand Down
42 changes: 42 additions & 0 deletions painter/src/text.rs
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,48 @@ pub struct TextStyle {
pub overflow: TextOverflow,
}

/// use to update config of text style.
#[derive(Clone, Debug, PartialEq, Default)]
pub struct TextStyleOptional {
/// The size of fonts (in logical pixels) to use when painting the text.
pub font_size: Option<f32>,
/// The font face to use when painting the text.
pub font_face: Option<FontFace>,
/// The space between characters in logical pixel units.
pub letter_space: Option<f32>,
/// The line height of the text in logical pixels.
pub line_height: Option<f32>,
/// How to handle the visual overflow.
pub overflow: Option<TextOverflow>,
}

impl From<TextStyle> for TextStyleOptional {
fn from(value: TextStyle) -> Self {
Self {
font_size: Some(value.font_size),
font_face: Some(value.font_face),
letter_space: Some(value.letter_space),
line_height: Some(value.line_height),
overflow: Some(value.overflow),
}
}
}

impl TextStyleOptional {
pub fn merge(&self, origin: &TextStyle) -> TextStyle {
TextStyle {
font_size: self.font_size.unwrap_or(origin.font_size),
font_face: self
.font_face
.clone()
.unwrap_or(origin.font_face.clone()),
letter_space: self.letter_space.unwrap_or(origin.letter_space),
line_height: self.line_height.unwrap_or(origin.line_height),
overflow: self.overflow.unwrap_or(origin.overflow),
}
}
}

#[derive(Clone, Copy, PartialEq, Eq, Hash, Default, Debug)]
pub enum TextOverflow {
#[default]
Expand Down
86 changes: 44 additions & 42 deletions painter/src/text/typography_store.rs
Original file line number Diff line number Diff line change
Expand Up @@ -317,7 +317,7 @@ impl VisualGlyphs {
),
},
|glyph| {
let orign = Point::new(
let origin = Point::new(
self.to_pixel_value(glyph.x_offset + line.x),
self.to_pixel_value(glyph.y_offset + line.y),
);
Expand All @@ -327,7 +327,7 @@ impl VisualGlyphs {
Size::new(self.to_pixel_value(glyph.x_advance), self.to_pixel_value(line.height))
}
};
Rect::new(orign, size)
Rect::new(origin, size)
},
);
rc.origin += Point::new(self.to_pixel_value(self.x), self.to_pixel_value(self.y)).to_vector();
Expand All @@ -343,51 +343,53 @@ impl VisualGlyphs {
}

pub fn select_range(&self, rg: &Range<usize>) -> Vec<Rect> {
struct TypoRectJointer {
acc: Vec<Rect>,
cur: Option<Rect>,
}

impl TypoRectJointer {
fn new() -> Self { Self { acc: vec![], cur: None } }
fn join_x(&mut self, next: Rect) {
if let Some(rc) = &mut self.cur {
rc.size.width = next.max_x() - rc.min_x();
} else {
self.cur = Some(next);
}
}
fn new_rect(&mut self) {
let cur = self.cur.take();
if let Some(rc) = cur {
self.acc.push(rc);
}
}
fn rects(self) -> Vec<Rect> { self.acc }
}
let mut jointer = TypoRectJointer::new();
let mut rects = vec![];
for line in &self.visual_info.visual_lines {
let height = self.to_pixel_value(line.height);
let offset_x = self.x + line.x;
let offset_y = self.y + line.y;
for glyph in &line.glyphs {
let mut inline: Vec<(usize, usize)> = vec![];
for (i, glyph) in line.glyphs.iter().enumerate() {
if rg.contains(&(glyph.cluster as usize)) {
let glyph = glyph.clone().cast_to(self.font_size);
let rc = Rect::new(
Point::new(
self.to_pixel_value(glyph.x_offset + offset_x),
self.to_pixel_value(glyph.y_offset + offset_y),
),
Size::new(self.to_pixel_value(glyph.x_advance), height),
);
jointer.join_x(rc);
} else {
jointer.new_rect();
if let Some((_, end)) = inline
.last_mut()
.filter(|(_, end)| (*end + 1) == i)
{
*end += 1;
} else {
inline.push((i, i));
}
}
}
jointer.new_rect();

if !inline.is_empty() {
let is_horizontal = !self.visual_info.line_dir.is_horizontal();
let offset_x = self.x + line.x;
let offset_y = self.y + line.y;
inline.into_iter().for_each(|(start, end)| {
let (x_min, x_max, y_min, y_max) = if is_horizontal {
(
line.glyphs[start].x_offset,
line.glyphs[end].x_offset + line.glyphs[end].x_advance,
GlyphUnit::ZERO,
line.height,
)
} else {
(
GlyphUnit::ZERO,
line.width,
line.glyphs[start].y_offset,
line.glyphs[end].y_offset + line.glyphs[end].y_advance,
)
};
let rect = Rect::from_points([
Point::new(self.to_pixel_value(x_min), self.to_pixel_value(y_min)),
Point::new(self.to_pixel_value(x_max), self.to_pixel_value(y_max)),
]);
rects.push(
rect.translate((self.to_pixel_value(offset_x), self.to_pixel_value(offset_y)).into()),
);
});
}
}
jointer.rects()
rects
}

fn to_pixel_value(&self, v: GlyphUnit) -> f32 { v.cast_to(self.font_size).into_pixel() }
Expand Down
3 changes: 2 additions & 1 deletion themes/material/src/classes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,12 @@ use ribir_core::prelude::Classes;

mod buttons_cls;
mod checkbox_cls;
mod input_cls;
mod progress_cls;
mod radio_cls;
mod scrollbar_cls;
mod slider_cls;
mod tooltips_cls;

pub fn initd_classes() -> Classes {
let mut classes = Classes::default();

Expand All @@ -18,6 +18,7 @@ pub fn initd_classes() -> Classes {
checkbox_cls::init(&mut classes);
tooltips_cls::init(&mut classes);
slider_cls::init(&mut classes);
input_cls::init(&mut classes);

classes
}
27 changes: 27 additions & 0 deletions themes/material/src/classes/input_cls.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
use ribir_core::prelude::*;
use ribir_widgets::{input::TEXT_CARET, prelude::*};

use crate::md;

pub(super) fn init(classes: &mut Classes) {
classes.insert(TEXT_CARET, |_w| {
fn_widget! {
let mut w = @ FittedBox {
box_fit: BoxFit::CoverY,
@ { svgs::TEXT_CARET }
};
let blink_interval = Duration::from_millis(500);
let unsub = interval(blink_interval, AppCtx::scheduler())
.subscribe(move |idx| $w.write().opacity = (idx % 2) as f32);
@ $w {
on_disposed: move |_| unsub.unsubscribe()
}
}
.into_widget()
});

classes.insert(TEXT_HIGH_LIGHT, style_class! {
background: Color::from_rgb(181, 215, 254),
border_radius: md::RADIUS_2,
});
}
16 changes: 0 additions & 16 deletions themes/material/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -74,16 +74,6 @@ const AVATAR_RADIUS: f32 = 20.;
const LIST_IMAGE_ITEM_SIZE: f32 = 56.;

fn init_custom_style(theme: &mut Theme) {
theme
.custom_styles
.set_custom_style(InputStyle { size: Some(20.) });
theme
.custom_styles
.set_custom_style(TextAreaStyle { rows: Some(2.), cols: Some(20.) });
theme
.custom_styles
.set_custom_style(SelectedHighLightStyle { brush: Color::from_rgb(181, 215, 254).into() });

theme.custom_styles.set_custom_style(TabsStyle {
extent_with_both: 64.,
extent_only_label: 48.,
Expand Down Expand Up @@ -153,12 +143,6 @@ fn init_custom_style(theme: &mut Theme) {
},
},
});
theme
.custom_styles
.set_custom_style(PlaceholderStyle {
foreground: theme.palette.on_surface_variant().into(),
text_style: theme.typography_theme.body_medium.text.clone(),
});
}

fn override_compose_decorator(theme: &mut Theme) {
Expand Down
Loading

0 comments on commit 7954222

Please sign in to comment.