From 30bcc2a4de93375285e8a8d93bf67cd238b40e96 Mon Sep 17 00:00:00 2001 From: T-256 Date: Mon, 20 Jul 2026 15:33:59 +0330 Subject: [PATCH 1/5] remove unnecessery features --- crates/twill-iced/Cargo.toml | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/crates/twill-iced/Cargo.toml b/crates/twill-iced/Cargo.toml index 6246028..416a462 100644 --- a/crates/twill-iced/Cargo.toml +++ b/crates/twill-iced/Cargo.toml @@ -15,7 +15,10 @@ categories = ["gui", "rendering"] [dependencies] twill-core = { path = "../twill-core", version = "0.3.0" } twill-backend-common = { path = "../twill-backend-common", version = "0.3.0" } -iced = { version = "0.14", default-features = false, features = ["advanced", "image", "tokio", "canvas", "wgpu", "wayland", "x11"] } +iced = { version = "0.14", default-features = false, features = ["canvas"] } + +[features] +default = [] [package.metadata.docs.rs] rustdoc-args = ["--cfg", "docsrs"] From fd3b69b1175dfa39253bb4147d90ab7552ab179d Mon Sep 17 00:00:00 2001 From: T-256 Date: Tue, 21 Jul 2026 23:20:18 +0330 Subject: [PATCH 2/5] replace iced with iced_core where possible --- Cargo.lock | 1 + crates/twill-iced/Cargo.toml | 1 + crates/twill-iced/src/convert.rs | 28 +-- crates/twill-iced/src/lib.rs | 18 +- crates/twill-iced/src/widgets/common.rs | 4 +- crates/twill-iced/src/widgets/container.rs | 17 +- crates/twill-iced/src/widgets/conversions.rs | 180 +++++++++---------- crates/twill-iced/src/widgets/flex.rs | 20 +-- crates/twill-iced/src/widgets/grid.rs | 16 +- crates/twill-iced/src/widgets/layout.rs | 28 +-- crates/twill-iced/src/widgets/ratio_boxes.rs | 24 +-- crates/twill-iced/src/widgets/tests.rs | 50 +++--- 12 files changed, 195 insertions(+), 192 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 5e669e2..4266697 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -5600,6 +5600,7 @@ name = "twill-iced" version = "0.3.0" dependencies = [ "iced", + "iced_core", "twill-backend-common", "twill-core", ] diff --git a/crates/twill-iced/Cargo.toml b/crates/twill-iced/Cargo.toml index 416a462..d3d4450 100644 --- a/crates/twill-iced/Cargo.toml +++ b/crates/twill-iced/Cargo.toml @@ -16,6 +16,7 @@ categories = ["gui", "rendering"] twill-core = { path = "../twill-core", version = "0.3.0" } twill-backend-common = { path = "../twill-backend-common", version = "0.3.0" } iced = { version = "0.14", default-features = false, features = ["canvas"] } +iced_core = { version = "0.14", features = ["advanced"] } [features] default = [] diff --git a/crates/twill-iced/src/convert.rs b/crates/twill-iced/src/convert.rs index 578c29c..3c3c84b 100644 --- a/crates/twill-iced/src/convert.rs +++ b/crates/twill-iced/src/convert.rs @@ -13,15 +13,15 @@ pub enum TextDirection { RightToLeft, } -pub fn to_color(color: Color) -> iced::Color { +pub fn to_color(color: Color) -> iced_core::Color { super::widgets::to_color(color) } -pub fn to_color_value(value: ColorValue) -> iced::Color { +pub fn to_color_value(value: ColorValue) -> iced_core::Color { super::widgets::to_color_value(value) } -pub fn to_padding(spacing: Spacing) -> iced::Padding { +pub fn to_padding(spacing: Spacing) -> iced_core::Padding { super::widgets::to_padding(spacing) } @@ -37,19 +37,19 @@ pub fn to_aspect_ratio(ratio: AspectRatio) -> Option { super::widgets::to_aspect_ratio(ratio) } -pub fn to_content_fit(fit: ObjectFit) -> iced::ContentFit { +pub fn to_content_fit(fit: ObjectFit) -> iced_core::ContentFit { super::widgets::to_content_fit(fit) } -pub fn to_shadow_with_color(shadow: Shadow, color: ShadowColor) -> iced::Shadow { +pub fn to_shadow_with_color(shadow: Shadow, color: ShadowColor) -> iced_core::Shadow { super::widgets::to_shadow_with_color(shadow, color) } -pub fn to_shadow_layers_with_color(shadow: Shadow, color: ShadowColor) -> Vec { +pub fn to_shadow_layers_with_color(shadow: Shadow, color: ShadowColor) -> Vec { super::widgets::to_shadow_layers_with_color(shadow, color) } -pub fn to_shadow(shadow: Shadow, color: Color) -> iced::Shadow { +pub fn to_shadow(shadow: Shadow, color: Color) -> iced_core::Shadow { super::widgets::to_shadow(shadow, color) } @@ -61,18 +61,18 @@ pub fn resolve_font_size(size: FontSize, custom_properties: &[(&str, f32)]) -> O super::widgets::resolve_font_size(size, custom_properties) } -pub fn to_font_weight(weight: FontWeight) -> iced::font::Weight { +pub fn to_font_weight(weight: FontWeight) -> iced_core::font::Weight { super::widgets::to_font_weight(weight) } -pub fn to_text_alignment(align: TextAlign) -> iced::widget::text::Alignment { +pub fn to_text_alignment(align: TextAlign) -> iced_core::widget::text::Alignment { super::widgets::to_text_alignment(align) } pub fn to_text_alignment_with_direction( align: TextAlign, direction: TextDirection, -) -> iced::widget::text::Alignment { +) -> iced_core::widget::text::Alignment { super::widgets::to_text_alignment_with_direction(align, direction) } @@ -80,11 +80,11 @@ pub fn to_semantic_color_with_theme( semantic: SemanticColor, semantic_theme: &S, variant: ThemeVariant, -) -> iced::Color { +) -> iced_core::Color { super::widgets::to_semantic_color_with_theme(semantic, semantic_theme, variant) } -pub fn to_semantic_color(semantic: SemanticColor, variant: ThemeVariant) -> iced::Color { +pub fn to_semantic_color(semantic: SemanticColor, variant: ThemeVariant) -> iced_core::Color { super::widgets::to_semantic_color(semantic, variant) } @@ -92,10 +92,10 @@ pub fn to_duration(duration: TransitionDuration) -> std::time::Duration { super::widgets::to_duration(duration) } -pub fn to_easing(easing: Easing) -> iced::animation::Easing { +pub fn to_easing(easing: Easing) -> iced_core::animation::Easing { super::widgets::to_easing(easing) } -pub fn to_interaction(cursor: Cursor) -> iced::mouse::Interaction { +pub fn to_interaction(cursor: Cursor) -> iced_core::mouse::Interaction { super::widgets::to_interaction(cursor) } diff --git a/crates/twill-iced/src/lib.rs b/crates/twill-iced/src/lib.rs index 880f0d8..a353114 100644 --- a/crates/twill-iced/src/lib.rs +++ b/crates/twill-iced/src/lib.rs @@ -3,7 +3,7 @@ mod convert; mod widgets; -use iced::ContentFit; +use iced_core::ContentFit; use twill_core::tokens::{ AspectRatio, Blur, BorderRadius, Color, ColorValue, Cursor, Easing, FontSize, FontWeight, Shadow, Spacing, TextAlign, TransitionDuration, @@ -50,7 +50,7 @@ pub trait ToIced: private::Sealed { impl private::Sealed for Color {} impl ToIced for Color { - type Output = iced::Color; + type Output = iced_core::Color; fn to_iced(self) -> Self::Output { to_color(self) @@ -59,7 +59,7 @@ impl ToIced for Color { impl private::Sealed for ColorValue {} impl ToIced for ColorValue { - type Output = iced::Color; + type Output = iced_core::Color; fn to_iced(self) -> Self::Output { to_color_value(self) @@ -68,7 +68,7 @@ impl ToIced for ColorValue { impl private::Sealed for Spacing {} impl ToIced for Spacing { - type Output = iced::Padding; + type Output = iced_core::Padding; fn to_iced(self) -> Self::Output { to_padding(self) @@ -113,7 +113,7 @@ impl ToIced for ObjectFit { impl private::Sealed for Shadow {} impl ToIced for Shadow { - type Output = iced::Shadow; + type Output = iced_core::Shadow; fn to_iced(self) -> Self::Output { to_shadow_with_color(self, twill_backend_common::ShadowColor::Default) @@ -131,7 +131,7 @@ impl ToIced for FontSize { impl private::Sealed for FontWeight {} impl ToIced for FontWeight { - type Output = iced::font::Weight; + type Output = iced_core::font::Weight; fn to_iced(self) -> Self::Output { to_font_weight(self) @@ -140,7 +140,7 @@ impl ToIced for FontWeight { impl private::Sealed for TextAlign {} impl ToIced for TextAlign { - type Output = iced::widget::text::Alignment; + type Output = iced_core::widget::text::Alignment; fn to_iced(self) -> Self::Output { to_text_alignment(self) @@ -158,7 +158,7 @@ impl ToIced for TransitionDuration { impl private::Sealed for Easing {} impl ToIced for Easing { - type Output = iced::animation::Easing; + type Output = iced_core::animation::Easing; fn to_iced(self) -> Self::Output { to_easing(self) @@ -167,7 +167,7 @@ impl ToIced for Easing { impl private::Sealed for Cursor {} impl ToIced for Cursor { - type Output = iced::mouse::Interaction; + type Output = iced_core::mouse::Interaction; fn to_iced(self) -> Self::Output { to_interaction(self) diff --git a/crates/twill-iced/src/widgets/common.rs b/crates/twill-iced/src/widgets/common.rs index 19618a6..0147d48 100644 --- a/crates/twill-iced/src/widgets/common.rs +++ b/crates/twill-iced/src/widgets/common.rs @@ -1,9 +1,9 @@ -use iced::Size; +use iced_core::Size; use twill_core::style::Style; use twill_core::tokens::{ColorValue, Container, Spacing}; use twill_core::utilities::Columns; -pub(super) fn apply_opacity_to_color(mut color: iced::Color, opacity: f32) -> iced::Color { +pub(super) fn apply_opacity_to_color(mut color: iced_core::Color, opacity: f32) -> iced_core::Color { if opacity.is_finite() { color.a *= opacity.clamp(0.0, 1.0); } diff --git a/crates/twill-iced/src/widgets/container.rs b/crates/twill-iced/src/widgets/container.rs index 4a96cab..0bf8b9d 100644 --- a/crates/twill-iced/src/widgets/container.rs +++ b/crates/twill-iced/src/widgets/container.rs @@ -1,5 +1,6 @@ +use iced::Renderer; use iced::widget::{canvas, stack}; -use iced::{Point, Rectangle, Renderer, Size, Theme, border, mouse}; +use iced_core::{Point, Rectangle, Size, Theme, border, mouse}; use twill_core::style::Style; use twill_core::tokens::BorderStyle; @@ -107,7 +108,7 @@ pub(super) fn styled_container_with_custom_properties_and_semantic_theme< }) .map(to_color_value) .map(|color| apply_opacity_to_color(color, opacity)) - .unwrap_or(iced::Color::TRANSPARENT); + .unwrap_or(iced_core::Color::TRANSPARENT); let border_style = style.border_style_value().unwrap_or(BorderStyle::Solid); let border_width = base_border_width; let shadow_layers = style @@ -130,8 +131,8 @@ pub(super) fn styled_container_with_custom_properties_and_semantic_theme< container = container.padding(p); } let base = container.style(move |_| iced::widget::container::Style { - background: bg_color.map(iced::Background::Color), - border: iced::Border { + background: bg_color.map(iced_core::Background::Color), + border: iced_core::Border { radius: border_radius.into(), width: border_width, color: border_color, @@ -154,8 +155,8 @@ pub(super) fn styled_container_with_custom_properties_and_semantic_theme< border_color, background: bg_color, }) - .width(iced::Length::Fill) - .height(iced::Length::Fill); + .width(iced_core::Length::Fill) + .height(iced_core::Length::Fill); let base = iced::widget::container(stack![border_layer, content_layer]); wrap_with_shadow_layers(base.into(), &shadow_layers, border_radius) @@ -167,8 +168,8 @@ struct BorderCanvas { border_style: BorderStyle, border_width: f32, border_radius: f32, - border_color: iced::Color, - background: Option, + border_color: iced_core::Color, + background: Option, } impl canvas::Program for BorderCanvas { diff --git a/crates/twill-iced/src/widgets/conversions.rs b/crates/twill-iced/src/widgets/conversions.rs index 7b5e4b3..8af0c3f 100644 --- a/crates/twill-iced/src/widgets/conversions.rs +++ b/crates/twill-iced/src/widgets/conversions.rs @@ -1,4 +1,4 @@ -use iced::{ContentFit, Length}; +use iced_core::{ContentFit, Length}; use twill_backend_common::ShadowColor; use twill_core::tokens::{ AspectRatio, BackgroundColor, Blur, BorderColor, BorderRadius, Color, ColorValue, Cursor, @@ -12,14 +12,14 @@ use super::common::{apply_opacity_to_color, container_to_px, spacing_to_px}; pub use crate::convert::TextDirection; pub use twill_core::tokens::SemanticThemeSource; -pub fn to_color(color: Color) -> iced::Color { +pub fn to_color(color: Color) -> iced_core::Color { to_color_value(color.compute()) } /// Convert twill ColorValue to iced Color. -pub fn to_color_value(value: twill_core::tokens::ColorValue) -> iced::Color { +pub fn to_color_value(value: twill_core::tokens::ColorValue) -> iced_core::Color { let (r, g, b) = value.to_rgb8(); - iced::Color::from_rgba( + iced_core::Color::from_rgba( r as f32 / 255.0, g as f32 / 255.0, b as f32 / 255.0, @@ -95,17 +95,17 @@ pub(crate) fn resolve_background_color_token_with_semantic_theme< } /// Convert twill Spacing to iced Padding. -pub fn to_padding(spacing: Spacing) -> iced::Padding { - iced::Padding::new(spacing_to_px(spacing)) +pub fn to_padding(spacing: Spacing) -> iced_core::Padding { + iced_core::Padding::new(spacing_to_px(spacing)) } /// Convert twill easing tokens into iced animation easing curves. -pub fn to_easing(easing: Easing) -> iced::animation::Easing { +pub fn to_easing(easing: Easing) -> iced_core::animation::Easing { match easing { - Easing::Linear => iced::animation::Easing::Linear, - Easing::In => iced::animation::Easing::EaseIn, - Easing::Out => iced::animation::Easing::EaseOut, - Easing::InOut => iced::animation::Easing::EaseInOut, + Easing::Linear => iced_core::animation::Easing::Linear, + Easing::In => iced_core::animation::Easing::EaseIn, + Easing::Out => iced_core::animation::Easing::EaseOut, + Easing::InOut => iced_core::animation::Easing::EaseInOut, } } @@ -137,8 +137,8 @@ fn resolve_padding_value_px(value: PaddingValue, custom_properties: &[(&str, f32 pub(crate) fn to_style_padding( padding: twill_core::utilities::Padding, custom_properties: &[(&str, f32)], -) -> iced::Padding { - iced::Padding { +) -> iced_core::Padding { + iced_core::Padding { top: padding .top_side() .map(|value| resolve_padding_value_px(value, custom_properties)) @@ -430,67 +430,67 @@ pub fn to_content_fit(fit: ObjectFit) -> ContentFit { } /// Convert twill Shadow to iced Shadow with an optional color override. -pub fn to_shadow_with_color(shadow: Shadow, color: ShadowColor) -> iced::Shadow { +pub fn to_shadow_with_color(shadow: Shadow, color: ShadowColor) -> iced_core::Shadow { let base = match color { ShadowColor::Default => Color::black(), ShadowColor::Explicit(color) => color, }; let mut color = to_color(base); match shadow { - Shadow::None => iced::Shadow::default(), + Shadow::None => iced_core::Shadow::default(), Shadow::Xs2 => { color.a *= 0.05; - iced::Shadow { + iced_core::Shadow { color, - offset: iced::Vector::new(0.0, 1.0), + offset: iced_core::Vector::new(0.0, 1.0), blur_radius: 0.0, } } Shadow::Xs => { color.a *= 0.05; - iced::Shadow { + iced_core::Shadow { color, - offset: iced::Vector::new(0.0, 1.0), + offset: iced_core::Vector::new(0.0, 1.0), blur_radius: 2.0, } } Shadow::Sm => { color.a *= 0.1; - iced::Shadow { + iced_core::Shadow { color, - offset: iced::Vector::new(0.0, 1.0), + offset: iced_core::Vector::new(0.0, 1.0), blur_radius: 3.0, } } Shadow::Md => { color.a *= 0.1; - iced::Shadow { + iced_core::Shadow { color, - offset: iced::Vector::new(0.0, 4.0), + offset: iced_core::Vector::new(0.0, 4.0), blur_radius: 6.0, } } Shadow::Lg => { color.a *= 0.1; - iced::Shadow { + iced_core::Shadow { color, - offset: iced::Vector::new(0.0, 10.0), + offset: iced_core::Vector::new(0.0, 10.0), blur_radius: 15.0, } } Shadow::Xl => { color.a *= 0.1; - iced::Shadow { + iced_core::Shadow { color, - offset: iced::Vector::new(0.0, 20.0), + offset: iced_core::Vector::new(0.0, 20.0), blur_radius: 25.0, } } Shadow::S2xl => { color.a *= 0.25; - iced::Shadow { + iced_core::Shadow { color, - offset: iced::Vector::new(0.0, 25.0), + offset: iced_core::Vector::new(0.0, 25.0), blur_radius: 50.0, } } @@ -502,7 +502,7 @@ pub fn to_shadow_with_color(shadow: Shadow, color: ShadowColor) -> iced::Shadow /// Tailwind defines multiple box-shadow layers for some tokens (`sm`, `md`, `lg`, `xl`). /// Iced supports only one shadow per container, so layered fidelity is achieved /// by wrapping content with multiple shadow containers. -pub fn to_shadow_layers_with_color(shadow: Shadow, color: ShadowColor) -> Vec { +pub fn to_shadow_layers_with_color(shadow: Shadow, color: ShadowColor) -> Vec { let layers: &[(f32, f32, f32)] = match shadow { Shadow::None => &[], Shadow::Xs2 => &[(1.0, 0.0, 0.05)], @@ -523,9 +523,9 @@ pub fn to_shadow_layers_with_color(shadow: Shadow, color: ShadowColor) -> Vec Vec Vec { +) -> Vec { let layers: &[(f32, f32, f32)] = match shadow { Shadow::None => &[], Shadow::Xs2 => &[(1.0, 0.0, 0.05)], @@ -552,9 +552,9 @@ pub(super) fn to_shadow_layers_with_color_value( .map(|(offset_y, blur, alpha)| { let mut c = to_color_value(color); c.a *= *alpha; - iced::Shadow { + iced_core::Shadow { color: c, - offset: iced::Vector::new(0.0, *offset_y), + offset: iced_core::Vector::new(0.0, *offset_y), blur_radius: *blur, } }) @@ -565,7 +565,7 @@ pub(super) fn shadow_layers_with_opacity( shadow: Shadow, color: ShadowColor, opacity: f32, -) -> Vec { +) -> Vec { let mut layers = to_shadow_layers_with_color(shadow, color); for layer in &mut layers { layer.color = apply_opacity_to_color(layer.color, opacity); @@ -577,7 +577,7 @@ pub(super) fn shadow_layers_with_color_value_and_opacity( shadow: Shadow, color: ColorValue, opacity: f32, -) -> Vec { +) -> Vec { let mut layers = to_shadow_layers_with_color_value(shadow, color); for layer in &mut layers { layer.color = apply_opacity_to_color(layer.color, opacity); @@ -587,7 +587,7 @@ pub(super) fn shadow_layers_with_color_value_and_opacity( pub(super) fn wrap_with_shadow_layers<'a, Message: 'a>( content: iced::Element<'a, Message>, - layers: &[iced::Shadow], + layers: &[iced_core::Shadow], border_radius: f32, ) -> iced::widget::Container<'a, Message> { let mut current = content; @@ -595,10 +595,10 @@ pub(super) fn wrap_with_shadow_layers<'a, Message: 'a>( for shadow in layers.iter().copied().rev() { current = iced::widget::container(current) .style(move |_| iced::widget::container::Style { - border: iced::Border { + border: iced_core::Border { radius: border_radius.into(), width: 0.0, - color: iced::Color::TRANSPARENT, + color: iced_core::Color::TRANSPARENT, }, shadow, ..Default::default() @@ -610,7 +610,7 @@ pub(super) fn wrap_with_shadow_layers<'a, Message: 'a>( } /// Convert twill Shadow to iced Shadow. -pub fn to_shadow(shadow: Shadow, color: Color) -> iced::Shadow { +pub fn to_shadow(shadow: Shadow, color: Color) -> iced_core::Shadow { to_shadow_with_color(shadow, ShadowColor::Explicit(color)) } @@ -625,17 +625,17 @@ pub fn resolve_font_size(size: FontSize, custom_properties: &[(&str, f32)]) -> O } /// Convert twill FontWeight to iced font Weight -pub fn to_font_weight(weight: FontWeight) -> iced::font::Weight { +pub fn to_font_weight(weight: FontWeight) -> iced_core::font::Weight { match weight { - FontWeight::Thin => iced::font::Weight::Thin, - FontWeight::ExtraLight => iced::font::Weight::ExtraLight, - FontWeight::Light => iced::font::Weight::Light, - FontWeight::Normal => iced::font::Weight::Normal, - FontWeight::Medium => iced::font::Weight::Medium, - FontWeight::SemiBold => iced::font::Weight::Semibold, - FontWeight::Bold => iced::font::Weight::Bold, - FontWeight::ExtraBold => iced::font::Weight::ExtraBold, - FontWeight::Black => iced::font::Weight::Black, + FontWeight::Thin => iced_core::font::Weight::Thin, + FontWeight::ExtraLight => iced_core::font::Weight::ExtraLight, + FontWeight::Light => iced_core::font::Weight::Light, + FontWeight::Normal => iced_core::font::Weight::Normal, + FontWeight::Medium => iced_core::font::Weight::Medium, + FontWeight::SemiBold => iced_core::font::Weight::Semibold, + FontWeight::Bold => iced_core::font::Weight::Bold, + FontWeight::ExtraBold => iced_core::font::Weight::ExtraBold, + FontWeight::Black => iced_core::font::Weight::Black, } } @@ -643,7 +643,7 @@ pub fn to_font_weight(weight: FontWeight) -> iced::font::Weight { /// /// For direction-aware logical alignment (`text-start` / `text-end`), /// use [`to_text_alignment_with_direction`]. -pub fn to_text_alignment(align: TextAlign) -> iced::widget::text::Alignment { +pub fn to_text_alignment(align: TextAlign) -> iced_core::widget::text::Alignment { to_text_alignment_with_direction(align, TextDirection::LeftToRight) } @@ -654,24 +654,24 @@ pub fn to_text_alignment(align: TextAlign) -> iced::widget::text::Alignment { pub fn to_text_alignment_with_direction( align: TextAlign, direction: TextDirection, -) -> iced::widget::text::Alignment { +) -> iced_core::widget::text::Alignment { match align { - TextAlign::Left => iced::widget::text::Alignment::Left, - TextAlign::Center => iced::widget::text::Alignment::Center, - TextAlign::Right => iced::widget::text::Alignment::Right, - TextAlign::Justify => iced::widget::text::Alignment::Justified, + TextAlign::Left => iced_core::widget::text::Alignment::Left, + TextAlign::Center => iced_core::widget::text::Alignment::Center, + TextAlign::Right => iced_core::widget::text::Alignment::Right, + TextAlign::Justify => iced_core::widget::text::Alignment::Justified, TextAlign::Start => { if matches!(direction, TextDirection::RightToLeft) { - iced::widget::text::Alignment::Right + iced_core::widget::text::Alignment::Right } else { - iced::widget::text::Alignment::Left + iced_core::widget::text::Alignment::Left } } TextAlign::End => { if matches!(direction, TextDirection::RightToLeft) { - iced::widget::text::Alignment::Left + iced_core::widget::text::Alignment::Left } else { - iced::widget::text::Alignment::Right + iced_core::widget::text::Alignment::Right } } } @@ -681,7 +681,7 @@ pub fn to_semantic_color_with_theme( semantic: SemanticColor, semantic_theme: &S, variant: ThemeVariant, -) -> iced::Color { +) -> iced_core::Color { let color = semantic_theme .resolve_value(semantic, variant) .unwrap_or_else(|| Color::black().compute()); @@ -689,7 +689,7 @@ pub fn to_semantic_color_with_theme( } /// Convert twill SemanticColor to iced Color based on the default semantic theme. -pub fn to_semantic_color(semantic: SemanticColor, variant: ThemeVariant) -> iced::Color { +pub fn to_semantic_color(semantic: SemanticColor, variant: ThemeVariant) -> iced_core::Color { to_semantic_color_with_theme(semantic, SemanticThemeVars::shadcn_neutral(), variant) } @@ -699,41 +699,41 @@ pub fn to_duration(duration: TransitionDuration) -> std::time::Duration { } /// Convert twill Cursor to iced mouse Interaction. -pub fn to_interaction(cursor: Cursor) -> iced::mouse::Interaction { +pub fn to_interaction(cursor: Cursor) -> iced_core::mouse::Interaction { match cursor { - Cursor::Auto | Cursor::Default => iced::mouse::Interaction::Idle, - Cursor::Pointer => iced::mouse::Interaction::Pointer, - Cursor::Wait => iced::mouse::Interaction::Wait, - Cursor::Progress => iced::mouse::Interaction::Progress, - Cursor::Text | Cursor::VerticalText => iced::mouse::Interaction::Text, - Cursor::Move => iced::mouse::Interaction::Move, - Cursor::Help => iced::mouse::Interaction::Help, - Cursor::NotAllowed => iced::mouse::Interaction::NotAllowed, - Cursor::NoDrop => iced::mouse::Interaction::NoDrop, - Cursor::None => iced::mouse::Interaction::None, - Cursor::ContextMenu => iced::mouse::Interaction::ContextMenu, - Cursor::Cell => iced::mouse::Interaction::Cell, - Cursor::Crosshair => iced::mouse::Interaction::Crosshair, - Cursor::Alias => iced::mouse::Interaction::Alias, - Cursor::Copy => iced::mouse::Interaction::Copy, - Cursor::Grab => iced::mouse::Interaction::Grab, - Cursor::Grabbing => iced::mouse::Interaction::Grabbing, - Cursor::AllScroll => iced::mouse::Interaction::AllScroll, - Cursor::ColResize => iced::mouse::Interaction::ResizingColumn, - Cursor::RowResize => iced::mouse::Interaction::ResizingRow, + Cursor::Auto | Cursor::Default => iced_core::mouse::Interaction::Idle, + Cursor::Pointer => iced_core::mouse::Interaction::Pointer, + Cursor::Wait => iced_core::mouse::Interaction::Wait, + Cursor::Progress => iced_core::mouse::Interaction::Progress, + Cursor::Text | Cursor::VerticalText => iced_core::mouse::Interaction::Text, + Cursor::Move => iced_core::mouse::Interaction::Move, + Cursor::Help => iced_core::mouse::Interaction::Help, + Cursor::NotAllowed => iced_core::mouse::Interaction::NotAllowed, + Cursor::NoDrop => iced_core::mouse::Interaction::NoDrop, + Cursor::None => iced_core::mouse::Interaction::None, + Cursor::ContextMenu => iced_core::mouse::Interaction::ContextMenu, + Cursor::Cell => iced_core::mouse::Interaction::Cell, + Cursor::Crosshair => iced_core::mouse::Interaction::Crosshair, + Cursor::Alias => iced_core::mouse::Interaction::Alias, + Cursor::Copy => iced_core::mouse::Interaction::Copy, + Cursor::Grab => iced_core::mouse::Interaction::Grab, + Cursor::Grabbing => iced_core::mouse::Interaction::Grabbing, + Cursor::AllScroll => iced_core::mouse::Interaction::AllScroll, + Cursor::ColResize => iced_core::mouse::Interaction::ResizingColumn, + Cursor::RowResize => iced_core::mouse::Interaction::ResizingRow, Cursor::NResize | Cursor::SResize | Cursor::NsResize => { - iced::mouse::Interaction::ResizingVertically + iced_core::mouse::Interaction::ResizingVertically } Cursor::EResize | Cursor::WResize | Cursor::EwResize => { - iced::mouse::Interaction::ResizingHorizontally + iced_core::mouse::Interaction::ResizingHorizontally } Cursor::NeResize | Cursor::SwResize | Cursor::NeswResize => { - iced::mouse::Interaction::ResizingDiagonallyUp + iced_core::mouse::Interaction::ResizingDiagonallyUp } Cursor::NwResize | Cursor::SeResize | Cursor::NwseResize => { - iced::mouse::Interaction::ResizingDiagonallyDown + iced_core::mouse::Interaction::ResizingDiagonallyDown } - Cursor::ZoomIn => iced::mouse::Interaction::ZoomIn, - Cursor::ZoomOut => iced::mouse::Interaction::ZoomOut, + Cursor::ZoomIn => iced_core::mouse::Interaction::ZoomIn, + Cursor::ZoomOut => iced_core::mouse::Interaction::ZoomOut, } } diff --git a/crates/twill-iced/src/widgets/flex.rs b/crates/twill-iced/src/widgets/flex.rs index 0f24ed5..461ba1a 100644 --- a/crates/twill-iced/src/widgets/flex.rs +++ b/crates/twill-iced/src/widgets/flex.rs @@ -1,4 +1,4 @@ -use iced::Length; +use iced_core::Length; use twill_core::style::Style; use twill_core::tokens::Spacing; use twill_core::utilities::{ @@ -15,23 +15,23 @@ pub(crate) fn is_reverse_direction(direction: FlexDirection) -> bool { ) } -pub(crate) fn row_alignment_for_items(items: AlignItems) -> iced::alignment::Vertical { +pub(crate) fn row_alignment_for_items(items: AlignItems) -> iced_core::alignment::Vertical { match items { - AlignItems::Start | AlignItems::Stretch => iced::alignment::Vertical::Top, - AlignItems::End | AlignItems::EndSafe => iced::alignment::Vertical::Bottom, - AlignItems::Center | AlignItems::CenterSafe => iced::alignment::Vertical::Center, - AlignItems::Baseline | AlignItems::BaselineLast => iced::alignment::Vertical::Bottom, + AlignItems::Start | AlignItems::Stretch => iced_core::alignment::Vertical::Top, + AlignItems::End | AlignItems::EndSafe => iced_core::alignment::Vertical::Bottom, + AlignItems::Center | AlignItems::CenterSafe => iced_core::alignment::Vertical::Center, + AlignItems::Baseline | AlignItems::BaselineLast => iced_core::alignment::Vertical::Bottom, } } -pub(crate) fn column_alignment_for_items(items: AlignItems) -> iced::alignment::Horizontal { +pub(crate) fn column_alignment_for_items(items: AlignItems) -> iced_core::alignment::Horizontal { match items { AlignItems::Start | AlignItems::Stretch | AlignItems::Baseline - | AlignItems::BaselineLast => iced::alignment::Horizontal::Left, - AlignItems::End | AlignItems::EndSafe => iced::alignment::Horizontal::Right, - AlignItems::Center | AlignItems::CenterSafe => iced::alignment::Horizontal::Center, + | AlignItems::BaselineLast => iced_core::alignment::Horizontal::Left, + AlignItems::End | AlignItems::EndSafe => iced_core::alignment::Horizontal::Right, + AlignItems::Center | AlignItems::CenterSafe => iced_core::alignment::Horizontal::Center, } } diff --git a/crates/twill-iced/src/widgets/grid.rs b/crates/twill-iced/src/widgets/grid.rs index 706c436..8bea3f1 100644 --- a/crates/twill-iced/src/widgets/grid.rs +++ b/crates/twill-iced/src/widgets/grid.rs @@ -1,9 +1,9 @@ -use iced::advanced::layout::{Layout as AdvancedLayout, Limits, Node}; -use iced::advanced::overlay; -use iced::advanced::renderer; -use iced::advanced::widget::{Operation, Tree}; -use iced::advanced::{Clipboard, Shell, Widget as AdvancedWidget}; -use iced::{Length, Point, Rectangle, Size, Vector, mouse}; +use iced_core::layout::{Layout as AdvancedLayout, Limits, Node}; +use iced_core::overlay; +use iced_core::renderer; +use iced_core::widget::{Operation, Tree}; +use iced_core::{Clipboard, Shell, Widget as AdvancedWidget}; +use iced_core::{Length, Point, Rectangle, Size, Vector, mouse}; use twill_core::style::Style; use twill_core::tokens::Spacing; use twill_core::utilities::{Columns, GridTemplate}; @@ -214,7 +214,7 @@ pub fn grid_template_columns_layout_with_context<'a, Message: Clone + 'a>( build_grid_template_columns_layout(items, track_count, gap) } -struct ColumnsFlow<'a, Message, Theme = iced::Theme, Renderer = iced::Renderer> { +struct ColumnsFlow<'a, Message, Theme = iced_core::Theme, Renderer = iced::Renderer> { elements: Vec>, columns: Columns, max_columns: usize, @@ -368,7 +368,7 @@ where fn update( &mut self, tree: &mut Tree, - event: &iced::Event, + event: &iced_core::Event, layout: AdvancedLayout<'_>, cursor: mouse::Cursor, renderer: &Renderer, diff --git a/crates/twill-iced/src/widgets/layout.rs b/crates/twill-iced/src/widgets/layout.rs index 2f172f4..7614828 100644 --- a/crates/twill-iced/src/widgets/layout.rs +++ b/crates/twill-iced/src/widgets/layout.rs @@ -1,4 +1,4 @@ -use iced::{Length, Point, Rectangle, Size, Vector, mouse}; +use iced_core::{Length, Point, Rectangle, Size, Vector, mouse}; use twill_core::style::Style; use twill_core::tokens::{SemanticThemeVars, ThemeVariant}; @@ -8,13 +8,13 @@ use super::conversions::{ resolve_height, resolve_width, to_aspect_ratio, to_style_margin, }; use super::ratio_boxes::{AspectRatioBox, HeightRatioBox, WidthRatioBox}; -use iced::advanced::layout::{Layout as AdvancedLayout, Limits, Node}; -use iced::advanced::overlay; -use iced::advanced::renderer; -use iced::advanced::widget::{Operation, Tree}; -use iced::advanced::{Clipboard, Shell, Widget as AdvancedWidget}; +use iced_core::layout::{Layout as AdvancedLayout, Limits, Node}; +use iced_core::overlay; +use iced_core::renderer; +use iced_core::widget::{Operation, Tree}; +use iced_core::{Clipboard, Shell, Widget as AdvancedWidget}; -struct MarginBox<'a, Message, Theme = iced::Theme, Renderer = iced::Renderer> { +struct MarginBox<'a, Message, Theme = iced_core::Theme, Renderer = iced::Renderer> { child: iced::Element<'a, Message, Theme, Renderer>, margin: MarginOffsets, width: Length, @@ -100,7 +100,7 @@ where fn update( &mut self, tree: &mut Tree, - event: &iced::Event, + event: &iced_core::Event, layout: AdvancedLayout<'_>, cursor: mouse::Cursor, renderer: &Renderer, @@ -212,7 +212,7 @@ fn apply_margin<'a, Message: Clone + 'a>( top: match resolved.top { Some(ResolvedMarginValue::Px(px)) => px, Some(ResolvedMarginValue::Auto) => { - vertical_auto = Some(iced::alignment::Vertical::Bottom); + vertical_auto = Some(iced_core::alignment::Vertical::Bottom); 0.0 } None => 0.0, @@ -220,7 +220,7 @@ fn apply_margin<'a, Message: Clone + 'a>( right: match resolved.right { Some(ResolvedMarginValue::Px(px)) => px, Some(ResolvedMarginValue::Auto) => { - horizontal_auto = Some(iced::alignment::Horizontal::Left); + horizontal_auto = Some(iced_core::alignment::Horizontal::Left); 0.0 } None => 0.0, @@ -228,7 +228,7 @@ fn apply_margin<'a, Message: Clone + 'a>( bottom: match resolved.bottom { Some(ResolvedMarginValue::Px(px)) => px, Some(ResolvedMarginValue::Auto) => { - vertical_auto = Some(iced::alignment::Vertical::Top); + vertical_auto = Some(iced_core::alignment::Vertical::Top); 0.0 } None => 0.0, @@ -236,7 +236,7 @@ fn apply_margin<'a, Message: Clone + 'a>( left: match resolved.left { Some(ResolvedMarginValue::Px(px)) => px, Some(ResolvedMarginValue::Auto) => { - horizontal_auto = Some(iced::alignment::Horizontal::Right); + horizontal_auto = Some(iced_core::alignment::Horizontal::Right); 0.0 } None => 0.0, @@ -246,13 +246,13 @@ fn apply_margin<'a, Message: Clone + 'a>( if matches!(resolved.left, Some(ResolvedMarginValue::Auto)) && matches!(resolved.right, Some(ResolvedMarginValue::Auto)) { - horizontal_auto = Some(iced::alignment::Horizontal::Center); + horizontal_auto = Some(iced_core::alignment::Horizontal::Center); } if matches!(resolved.top, Some(ResolvedMarginValue::Auto)) && matches!(resolved.bottom, Some(ResolvedMarginValue::Auto)) { - vertical_auto = Some(iced::alignment::Vertical::Center); + vertical_auto = Some(iced_core::alignment::Vertical::Center); } if !offsets.is_zero() { diff --git a/crates/twill-iced/src/widgets/ratio_boxes.rs b/crates/twill-iced/src/widgets/ratio_boxes.rs index 5b162ed..a952396 100644 --- a/crates/twill-iced/src/widgets/ratio_boxes.rs +++ b/crates/twill-iced/src/widgets/ratio_boxes.rs @@ -1,13 +1,13 @@ -use iced::advanced::layout::{Layout as AdvancedLayout, Limits, Node}; -use iced::advanced::overlay; -use iced::advanced::renderer; -use iced::advanced::widget::{Operation, Tree}; -use iced::advanced::{Clipboard, Shell, Widget as AdvancedWidget}; -use iced::{Length, Rectangle, Size, Vector, mouse}; +use iced_core::layout::{Layout as AdvancedLayout, Limits, Node}; +use iced_core::overlay; +use iced_core::renderer; +use iced_core::widget::{Operation, Tree}; +use iced_core::{Clipboard, Shell, Widget as AdvancedWidget}; +use iced_core::{Length, Rectangle, Size, Vector, mouse}; use super::common::resolve_aspect_size; -pub(super) struct AspectRatioBox<'a, Message, Theme = iced::Theme, Renderer = iced::Renderer> { +pub(super) struct AspectRatioBox<'a, Message, Theme = iced_core::Theme, Renderer = iced::Renderer> { child: iced::Element<'a, Message, Theme, Renderer>, ratio: f32, width: Length, @@ -98,7 +98,7 @@ where fn update( &mut self, tree: &mut Tree, - event: &iced::Event, + event: &iced_core::Event, layout: AdvancedLayout<'_>, cursor: mouse::Cursor, renderer: &Renderer, @@ -195,7 +195,7 @@ where } } -pub(super) struct WidthRatioBox<'a, Message, Theme = iced::Theme, Renderer = iced::Renderer> { +pub(super) struct WidthRatioBox<'a, Message, Theme = iced_core::Theme, Renderer = iced::Renderer> { child: iced::Element<'a, Message, Theme, Renderer>, ratio: f32, width: Length, @@ -294,7 +294,7 @@ where fn update( &mut self, tree: &mut Tree, - event: &iced::Event, + event: &iced_core::Event, layout: AdvancedLayout<'_>, cursor: mouse::Cursor, renderer: &Renderer, @@ -391,7 +391,7 @@ where } } -pub(super) struct HeightRatioBox<'a, Message, Theme = iced::Theme, Renderer = iced::Renderer> { +pub(super) struct HeightRatioBox<'a, Message, Theme = iced_core::Theme, Renderer = iced::Renderer> { child: iced::Element<'a, Message, Theme, Renderer>, ratio: f32, width: Length, @@ -490,7 +490,7 @@ where fn update( &mut self, tree: &mut Tree, - event: &iced::Event, + event: &iced_core::Event, layout: AdvancedLayout<'_>, cursor: mouse::Cursor, renderer: &Renderer, diff --git a/crates/twill-iced/src/widgets/tests.rs b/crates/twill-iced/src/widgets/tests.rs index a07ca07..9fee7d9 100644 --- a/crates/twill-iced/src/widgets/tests.rs +++ b/crates/twill-iced/src/widgets/tests.rs @@ -1,6 +1,6 @@ use super::*; use crate::TextDirection; -use iced::Length; +use iced_core::Length; use twill_core::prelude::*; use twill_core::tokens::AspectRatio; use twill_core::tokens::Scale; @@ -42,38 +42,38 @@ fn test_font_size_resolution_variants() { #[test] fn test_font_weight_mapping_variants() { - assert_eq!(to_font_weight(FontWeight::Thin), iced::font::Weight::Thin); + assert_eq!(to_font_weight(FontWeight::Thin), iced_core::font::Weight::Thin); assert_eq!( to_font_weight(FontWeight::ExtraLight), - iced::font::Weight::ExtraLight + iced_core::font::Weight::ExtraLight ); - assert_eq!(to_font_weight(FontWeight::Light), iced::font::Weight::Light); + assert_eq!(to_font_weight(FontWeight::Light), iced_core::font::Weight::Light); assert_eq!( to_font_weight(FontWeight::Normal), - iced::font::Weight::Normal + iced_core::font::Weight::Normal ); assert_eq!( to_font_weight(FontWeight::Medium), - iced::font::Weight::Medium + iced_core::font::Weight::Medium ); assert_eq!( to_font_weight(FontWeight::SemiBold), - iced::font::Weight::Semibold + iced_core::font::Weight::Semibold ); - assert_eq!(to_font_weight(FontWeight::Bold), iced::font::Weight::Bold); + assert_eq!(to_font_weight(FontWeight::Bold), iced_core::font::Weight::Bold); assert_eq!( to_font_weight(FontWeight::ExtraBold), - iced::font::Weight::ExtraBold + iced_core::font::Weight::ExtraBold ); - assert_eq!(to_font_weight(FontWeight::Black), iced::font::Weight::Black); + assert_eq!(to_font_weight(FontWeight::Black), iced_core::font::Weight::Black); } #[test] fn test_easing_mapping_variants() { - assert_eq!(to_easing(Easing::Linear), iced::animation::Easing::Linear); - assert_eq!(to_easing(Easing::In), iced::animation::Easing::EaseIn); - assert_eq!(to_easing(Easing::Out), iced::animation::Easing::EaseOut); - assert_eq!(to_easing(Easing::InOut), iced::animation::Easing::EaseInOut); + assert_eq!(to_easing(Easing::Linear), iced_core::animation::Easing::Linear); + assert_eq!(to_easing(Easing::In), iced_core::animation::Easing::EaseIn); + assert_eq!(to_easing(Easing::Out), iced_core::animation::Easing::EaseOut); + assert_eq!(to_easing(Easing::InOut), iced_core::animation::Easing::EaseInOut); } #[test] @@ -127,35 +127,35 @@ fn test_semantic_color_resolution_with_dynamic_theme() { fn test_text_alignment_mapping_variants() { assert_eq!( to_text_alignment(TextAlign::Left), - iced::widget::text::Alignment::Left + iced_core::widget::text::Alignment::Left ); assert_eq!( to_text_alignment(TextAlign::Center), - iced::widget::text::Alignment::Center + iced_core::widget::text::Alignment::Center ); assert_eq!( to_text_alignment(TextAlign::Right), - iced::widget::text::Alignment::Right + iced_core::widget::text::Alignment::Right ); assert_eq!( to_text_alignment(TextAlign::Justify), - iced::widget::text::Alignment::Justified + iced_core::widget::text::Alignment::Justified ); assert_eq!( to_text_alignment_with_direction(TextAlign::Start, TextDirection::LeftToRight), - iced::widget::text::Alignment::Left + iced_core::widget::text::Alignment::Left ); assert_eq!( to_text_alignment_with_direction(TextAlign::Start, TextDirection::RightToLeft), - iced::widget::text::Alignment::Right + iced_core::widget::text::Alignment::Right ); assert_eq!( to_text_alignment_with_direction(TextAlign::End, TextDirection::LeftToRight), - iced::widget::text::Alignment::Right + iced_core::widget::text::Alignment::Right ); assert_eq!( to_text_alignment_with_direction(TextAlign::End, TextDirection::RightToLeft), - iced::widget::text::Alignment::Left + iced_core::widget::text::Alignment::Left ); } @@ -566,15 +566,15 @@ fn test_flex_direction_layout_reverse_builds() { fn test_align_items_safe_and_baseline_mapping() { assert_eq!( row_alignment_for_items(AlignItems::EndSafe), - iced::alignment::Vertical::Bottom + iced_core::alignment::Vertical::Bottom ); assert_eq!( row_alignment_for_items(AlignItems::BaselineLast), - iced::alignment::Vertical::Bottom + iced_core::alignment::Vertical::Bottom ); assert_eq!( column_alignment_for_items(AlignItems::CenterSafe), - iced::alignment::Horizontal::Center + iced_core::alignment::Horizontal::Center ); } From b51426d2cc7c227313eba484b1ff1dc590e51864 Mon Sep 17 00:00:00 2001 From: T-256 Date: Tue, 21 Jul 2026 23:21:14 +0330 Subject: [PATCH 3/5] cargo fmt -p twill-iced --- crates/twill-iced/src/widgets/common.rs | 5 +++- crates/twill-iced/src/widgets/tests.rs | 35 ++++++++++++++++++++----- 2 files changed, 32 insertions(+), 8 deletions(-) diff --git a/crates/twill-iced/src/widgets/common.rs b/crates/twill-iced/src/widgets/common.rs index 0147d48..62ed028 100644 --- a/crates/twill-iced/src/widgets/common.rs +++ b/crates/twill-iced/src/widgets/common.rs @@ -3,7 +3,10 @@ use twill_core::style::Style; use twill_core::tokens::{ColorValue, Container, Spacing}; use twill_core::utilities::Columns; -pub(super) fn apply_opacity_to_color(mut color: iced_core::Color, opacity: f32) -> iced_core::Color { +pub(super) fn apply_opacity_to_color( + mut color: iced_core::Color, + opacity: f32, +) -> iced_core::Color { if opacity.is_finite() { color.a *= opacity.clamp(0.0, 1.0); } diff --git a/crates/twill-iced/src/widgets/tests.rs b/crates/twill-iced/src/widgets/tests.rs index 9fee7d9..2d70bff 100644 --- a/crates/twill-iced/src/widgets/tests.rs +++ b/crates/twill-iced/src/widgets/tests.rs @@ -42,12 +42,18 @@ fn test_font_size_resolution_variants() { #[test] fn test_font_weight_mapping_variants() { - assert_eq!(to_font_weight(FontWeight::Thin), iced_core::font::Weight::Thin); + assert_eq!( + to_font_weight(FontWeight::Thin), + iced_core::font::Weight::Thin + ); assert_eq!( to_font_weight(FontWeight::ExtraLight), iced_core::font::Weight::ExtraLight ); - assert_eq!(to_font_weight(FontWeight::Light), iced_core::font::Weight::Light); + assert_eq!( + to_font_weight(FontWeight::Light), + iced_core::font::Weight::Light + ); assert_eq!( to_font_weight(FontWeight::Normal), iced_core::font::Weight::Normal @@ -60,20 +66,35 @@ fn test_font_weight_mapping_variants() { to_font_weight(FontWeight::SemiBold), iced_core::font::Weight::Semibold ); - assert_eq!(to_font_weight(FontWeight::Bold), iced_core::font::Weight::Bold); + assert_eq!( + to_font_weight(FontWeight::Bold), + iced_core::font::Weight::Bold + ); assert_eq!( to_font_weight(FontWeight::ExtraBold), iced_core::font::Weight::ExtraBold ); - assert_eq!(to_font_weight(FontWeight::Black), iced_core::font::Weight::Black); + assert_eq!( + to_font_weight(FontWeight::Black), + iced_core::font::Weight::Black + ); } #[test] fn test_easing_mapping_variants() { - assert_eq!(to_easing(Easing::Linear), iced_core::animation::Easing::Linear); + assert_eq!( + to_easing(Easing::Linear), + iced_core::animation::Easing::Linear + ); assert_eq!(to_easing(Easing::In), iced_core::animation::Easing::EaseIn); - assert_eq!(to_easing(Easing::Out), iced_core::animation::Easing::EaseOut); - assert_eq!(to_easing(Easing::InOut), iced_core::animation::Easing::EaseInOut); + assert_eq!( + to_easing(Easing::Out), + iced_core::animation::Easing::EaseOut + ); + assert_eq!( + to_easing(Easing::InOut), + iced_core::animation::Easing::EaseInOut + ); } #[test] From ebb9eeedd6714fbdfecb150b7ad1d9e965df51e6 Mon Sep 17 00:00:00 2001 From: T-256 Date: Wed, 22 Jul 2026 00:39:59 +0330 Subject: [PATCH 4/5] add iced_widget and remove iced --- Cargo.lock | 2 +- crates/twill-iced/Cargo.toml | 7 +-- crates/twill-iced/src/widgets/common.rs | 6 ++ crates/twill-iced/src/widgets/container.rs | 27 ++++----- crates/twill-iced/src/widgets/conversions.rs | 10 ++-- crates/twill-iced/src/widgets/flex.rs | 62 ++++++++++---------- crates/twill-iced/src/widgets/grid.rs | 40 ++++++------- crates/twill-iced/src/widgets/layout.rs | 41 +++++++------ crates/twill-iced/src/widgets/ratio_boxes.rs | 54 ++++++++++++----- crates/twill-iced/src/widgets/tests.rs | 24 ++++---- 10 files changed, 151 insertions(+), 122 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 4266697..8eb7392 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -5599,8 +5599,8 @@ dependencies = [ name = "twill-iced" version = "0.3.0" dependencies = [ - "iced", "iced_core", + "iced_widget", "twill-backend-common", "twill-core", ] diff --git a/crates/twill-iced/Cargo.toml b/crates/twill-iced/Cargo.toml index d3d4450..69d895f 100644 --- a/crates/twill-iced/Cargo.toml +++ b/crates/twill-iced/Cargo.toml @@ -15,11 +15,8 @@ categories = ["gui", "rendering"] [dependencies] twill-core = { path = "../twill-core", version = "0.3.0" } twill-backend-common = { path = "../twill-backend-common", version = "0.3.0" } -iced = { version = "0.14", default-features = false, features = ["canvas"] } -iced_core = { version = "0.14", features = ["advanced"] } - -[features] -default = [] +iced_core = "0.14" +iced_widget = { version = "0.14", features = ["canvas"] } [package.metadata.docs.rs] rustdoc-args = ["--cfg", "docsrs"] diff --git a/crates/twill-iced/src/widgets/common.rs b/crates/twill-iced/src/widgets/common.rs index 62ed028..a460d37 100644 --- a/crates/twill-iced/src/widgets/common.rs +++ b/crates/twill-iced/src/widgets/common.rs @@ -3,6 +3,12 @@ use twill_core::style::Style; use twill_core::tokens::{ColorValue, Container, Spacing}; use twill_core::utilities::Columns; +/// A generic widget. +/// +/// This is an alias of an `iced_native` element with a default `Renderer`. +pub(super) type Element<'a, Message, Theme = iced_core::Theme, Renderer = iced_widget::Renderer> = + iced_core::Element<'a, Message, Theme, Renderer>; + pub(super) fn apply_opacity_to_color( mut color: iced_core::Color, opacity: f32, diff --git a/crates/twill-iced/src/widgets/container.rs b/crates/twill-iced/src/widgets/container.rs index 0bf8b9d..e7cb8ce 100644 --- a/crates/twill-iced/src/widgets/container.rs +++ b/crates/twill-iced/src/widgets/container.rs @@ -1,6 +1,5 @@ -use iced::Renderer; -use iced::widget::{canvas, stack}; use iced_core::{Point, Rectangle, Size, Theme, border, mouse}; +use iced_widget::{Renderer, canvas, stack}; use twill_core::style::Style; use twill_core::tokens::BorderStyle; @@ -16,9 +15,9 @@ use twill_backend_common::ShadowColor; use twill_core::tokens::{SemanticThemeVars, ThemeVariant}; pub fn styled_container<'a, Message: Clone + 'a>( - content: iced::Element<'a, Message>, + content: super::common::Element<'a, Message>, style: &Style, -) -> iced::widget::Container<'a, Message> { +) -> iced_widget::Container<'a, Message> { styled_container_with_custom_properties_and_semantic_theme( content, style, @@ -33,11 +32,11 @@ pub fn styled_container_with_semantic_theme< Message: Clone + 'a, S: SemanticThemeSource + ?Sized, >( - content: iced::Element<'a, Message>, + content: super::common::Element<'a, Message>, style: &Style, semantic_theme: &S, variant: ThemeVariant, -) -> iced::widget::Container<'a, Message> { +) -> iced_widget::Container<'a, Message> { styled_container_with_custom_properties_and_semantic_theme( content, style, @@ -49,10 +48,10 @@ pub fn styled_container_with_semantic_theme< /// Create a styled container with twill Style and explicit custom-property values. pub fn styled_container_with_custom_properties<'a, Message: Clone + 'a>( - content: iced::Element<'a, Message>, + content: super::common::Element<'a, Message>, style: &Style, custom_properties: &[(&str, f32)], -) -> iced::widget::Container<'a, Message> { +) -> iced_widget::Container<'a, Message> { styled_container_with_custom_properties_and_semantic_theme( content, style, @@ -67,12 +66,12 @@ pub(super) fn styled_container_with_custom_properties_and_semantic_theme< Message: Clone + 'a, S: SemanticThemeSource + ?Sized, >( - content: iced::Element<'a, Message>, + content: super::common::Element<'a, Message>, style: &Style, custom_properties: &[(&str, f32)], semantic_theme: &S, variant: ThemeVariant, -) -> iced::widget::Container<'a, Message> { +) -> iced_widget::Container<'a, Message> { let opacity = resolved_opacity(style); let padding = style .padding_value() @@ -126,11 +125,11 @@ pub(super) fn styled_container_with_custom_properties_and_semantic_theme< match border_style { BorderStyle::Solid => { - let mut container = iced::widget::container(content); + let mut container = iced_widget::container(content); if let Some(p) = padding { container = container.padding(p); } - let base = container.style(move |_| iced::widget::container::Style { + let base = container.style(move |_| iced_widget::container::Style { background: bg_color.map(iced_core::Background::Color), border: iced_core::Border { radius: border_radius.into(), @@ -143,7 +142,7 @@ pub(super) fn styled_container_with_custom_properties_and_semantic_theme< wrap_with_shadow_layers(base.into(), &shadow_layers, border_radius) } _ => { - let mut content_layer = iced::widget::container(content); + let mut content_layer = iced_widget::container(content); if let Some(p) = padding { content_layer = content_layer.padding(p); } @@ -158,7 +157,7 @@ pub(super) fn styled_container_with_custom_properties_and_semantic_theme< .width(iced_core::Length::Fill) .height(iced_core::Length::Fill); - let base = iced::widget::container(stack![border_layer, content_layer]); + let base = iced_widget::container(stack![border_layer, content_layer]); wrap_with_shadow_layers(base.into(), &shadow_layers, border_radius) } } diff --git a/crates/twill-iced/src/widgets/conversions.rs b/crates/twill-iced/src/widgets/conversions.rs index 8af0c3f..865f5ce 100644 --- a/crates/twill-iced/src/widgets/conversions.rs +++ b/crates/twill-iced/src/widgets/conversions.rs @@ -586,15 +586,15 @@ pub(super) fn shadow_layers_with_color_value_and_opacity( } pub(super) fn wrap_with_shadow_layers<'a, Message: 'a>( - content: iced::Element<'a, Message>, + content: super::common::Element<'a, Message>, layers: &[iced_core::Shadow], border_radius: f32, -) -> iced::widget::Container<'a, Message> { +) -> iced_widget::Container<'a, Message> { let mut current = content; for shadow in layers.iter().copied().rev() { - current = iced::widget::container(current) - .style(move |_| iced::widget::container::Style { + current = iced_widget::container(current) + .style(move |_| iced_widget::container::Style { border: iced_core::Border { radius: border_radius.into(), width: 0.0, @@ -606,7 +606,7 @@ pub(super) fn wrap_with_shadow_layers<'a, Message: 'a>( .into(); } - iced::widget::container(current) + iced_widget::container(current) } /// Convert twill Shadow to iced Shadow. diff --git a/crates/twill-iced/src/widgets/flex.rs b/crates/twill-iced/src/widgets/flex.rs index 461ba1a..c9c65ec 100644 --- a/crates/twill-iced/src/widgets/flex.rs +++ b/crates/twill-iced/src/widgets/flex.rs @@ -46,14 +46,14 @@ pub(crate) fn normalize_justify_content(justify: JustifyContent) -> JustifyConte fn main_axis_spacer<'a, Message: Clone + 'a>( direction: FlexDirection, portion: u16, -) -> iced::Element<'a, Message> { +) -> super::common::Element<'a, Message> { let portion = portion.max(1); match direction { - FlexDirection::Row | FlexDirection::RowReverse => iced::widget::Space::new() + FlexDirection::Row | FlexDirection::RowReverse => iced_widget::Space::new() .width(Length::FillPortion(portion)) .height(Length::Shrink) .into(), - FlexDirection::Col | FlexDirection::ColReverse => iced::widget::Space::new() + FlexDirection::Col | FlexDirection::ColReverse => iced_widget::Space::new() .width(Length::Shrink) .height(Length::FillPortion(portion)) .into(), @@ -61,10 +61,10 @@ fn main_axis_spacer<'a, Message: Clone + 'a>( } fn distribute_items_for_justify<'a, Message: Clone + 'a>( - items: Vec>, + items: Vec>, direction: FlexDirection, justify_content: Option, -) -> (Vec>, bool) { +) -> (Vec>, bool) { let justify = justify_content .map(normalize_justify_content) .unwrap_or(JustifyContent::Start); @@ -162,12 +162,12 @@ fn distribute_items_for_justify<'a, Message: Clone + 'a>( } fn flex_layout<'a, Message: Clone + 'a>( - mut items: Vec>, + mut items: Vec>, direction: FlexDirection, gap: Spacing, align_items: Option, justify_content: Option, -) -> iced::Element<'a, Message> { +) -> super::common::Element<'a, Message> { if is_reverse_direction(direction) { items.reverse(); } @@ -177,10 +177,10 @@ fn flex_layout<'a, Message: Clone + 'a>( .into_iter() .map(|item| match direction { FlexDirection::Row | FlexDirection::RowReverse => { - iced::widget::container(item).height(Length::Fill).into() + iced_widget::container(item).height(Length::Fill).into() } FlexDirection::Col | FlexDirection::ColReverse => { - iced::widget::container(item).width(Length::Fill).into() + iced_widget::container(item).width(Length::Fill).into() } }) .collect(); @@ -192,10 +192,10 @@ fn flex_layout<'a, Message: Clone + 'a>( .into_iter() .map(|item| match direction { FlexDirection::Row | FlexDirection::RowReverse => { - iced::widget::container(item).width(Length::Fill).into() + iced_widget::container(item).width(Length::Fill).into() } FlexDirection::Col | FlexDirection::ColReverse => { - iced::widget::container(item).height(Length::Fill).into() + iced_widget::container(item).height(Length::Fill).into() } }) .collect(); @@ -208,7 +208,7 @@ fn flex_layout<'a, Message: Clone + 'a>( match direction { FlexDirection::Row | FlexDirection::RowReverse => { - let mut row = iced::widget::Row::new().spacing(gap).width(Length::Fill); + let mut row = iced_widget::Row::new().spacing(gap).width(Length::Fill); if let Some(items) = align_items { row = row .align_y(row_alignment_for_items(items)) @@ -220,7 +220,7 @@ fn flex_layout<'a, Message: Clone + 'a>( row.into() } FlexDirection::Col | FlexDirection::ColReverse => { - let mut col = iced::widget::Column::new().spacing(gap).width(Length::Fill); + let mut col = iced_widget::Column::new().spacing(gap).width(Length::Fill); if let Some(items) = align_items { col = col.align_x(column_alignment_for_items(items)); } @@ -251,19 +251,19 @@ pub(crate) fn gap_on_main_axis( /// Create an iced flex layout for a given direction. pub fn flex_direction_layout<'a, Message: Clone + 'a>( - items: Vec>, + items: Vec>, direction: FlexDirection, gap: Spacing, -) -> iced::Element<'a, Message> { +) -> super::common::Element<'a, Message> { flex_layout(items, direction, gap, None, None) } /// Create an iced layout for `gap-*` utilities. pub fn gap_layout<'a, Message: Clone + 'a>( - items: Vec>, + items: Vec>, direction: FlexDirection, gap: Spacing, -) -> iced::Element<'a, Message> { +) -> super::common::Element<'a, Message> { flex_layout(items, direction, gap, None, None) } @@ -271,10 +271,10 @@ pub fn gap_layout<'a, Message: Clone + 'a>( /// /// In single-line flex layouts, this maps to the main axis for row directions. pub fn gap_x_layout<'a, Message: Clone + 'a>( - items: Vec>, + items: Vec>, direction: FlexDirection, gap_x: Spacing, -) -> iced::Element<'a, Message> { +) -> super::common::Element<'a, Message> { let gap = gap_on_main_axis(direction, None, None, Some(gap_x)); flex_layout(items, direction, gap, None, None) } @@ -283,31 +283,31 @@ pub fn gap_x_layout<'a, Message: Clone + 'a>( /// /// In single-line flex layouts, this maps to the main axis for column directions. pub fn gap_y_layout<'a, Message: Clone + 'a>( - items: Vec>, + items: Vec>, direction: FlexDirection, gap_y: Spacing, -) -> iced::Element<'a, Message> { +) -> super::common::Element<'a, Message> { let gap = gap_on_main_axis(direction, None, Some(gap_y), None); flex_layout(items, direction, gap, None, None) } /// Create an iced flex layout for a typed align-items value. pub fn align_items_layout<'a, Message: Clone + 'a>( - items: Vec>, + items: Vec>, direction: FlexDirection, gap: Spacing, align_items: AlignItems, -) -> iced::Element<'a, Message> { +) -> super::common::Element<'a, Message> { flex_layout(items, direction, gap, Some(align_items), None) } /// Create an iced flex layout for a typed justify-content value. pub fn justify_content_layout<'a, Message: Clone + 'a>( - items: Vec>, + items: Vec>, direction: FlexDirection, gap: Spacing, justify_content: JustifyContent, -) -> iced::Element<'a, Message> { +) -> super::common::Element<'a, Message> { flex_layout(items, direction, gap, None, Some(justify_content)) } @@ -401,21 +401,21 @@ fn custom_property_length(name: &str, vars: &[(&str, &str)]) -> Option { /// `direction` is the parent container direction and determines which axis receives /// the fill/shrink strategy. pub fn apply_flex_item<'a, Message: Clone + 'a>( - content: iced::Element<'a, Message>, + content: super::common::Element<'a, Message>, style: &Style, direction: FlexDirection, -) -> iced::Element<'a, Message> { +) -> super::common::Element<'a, Message> { apply_flex_item_with_custom_properties(content, style, direction, &[]) } /// Apply flex-item shorthand with custom property values resolver for /// `flex-()` use cases. pub fn apply_flex_item_with_custom_properties<'a, Message: Clone + 'a>( - content: iced::Element<'a, Message>, + content: super::common::Element<'a, Message>, style: &Style, direction: FlexDirection, custom_properties: &[(&str, &str)], -) -> iced::Element<'a, Message> { +) -> super::common::Element<'a, Message> { let numeric_custom_properties; let element = if style_uses_numeric_custom_properties(style) { numeric_custom_properties = custom_properties @@ -438,10 +438,10 @@ pub fn apply_flex_item_with_custom_properties<'a, Message: Clone + 'a>( }; let wrapper = match direction { FlexDirection::Row | FlexDirection::RowReverse => { - iced::widget::container(element).width(length) + iced_widget::container(element).width(length) } FlexDirection::Col | FlexDirection::ColReverse => { - iced::widget::container(element).height(length) + iced_widget::container(element).height(length) } }; diff --git a/crates/twill-iced/src/widgets/grid.rs b/crates/twill-iced/src/widgets/grid.rs index 8bea3f1..134720e 100644 --- a/crates/twill-iced/src/widgets/grid.rs +++ b/crates/twill-iced/src/widgets/grid.rs @@ -14,9 +14,9 @@ use super::common::{ }; pub fn columns_layout<'a, Message: Clone + 'a>( - items: Vec>, + items: Vec>, style: &Style, -) -> iced::Element<'a, Message> { +) -> super::common::Element<'a, Message> { let gap = style.column_gap_value().map_or(0.0, spacing_to_px); let max_columns = style .columns_max_count_value() @@ -30,7 +30,7 @@ pub fn columns_layout<'a, Message: Clone + 'a>( .width(Length::Fill) .into(), None => { - let mut fallback = iced::widget::Column::new().spacing(gap); + let mut fallback = iced_widget::Column::new().spacing(gap); for item in items { fallback = fallback.push(item); } @@ -141,15 +141,15 @@ pub(crate) fn resolve_grid_template_track_count( } fn build_grid_template_columns_layout<'a, Message: Clone + 'a>( - items: Vec>, + items: Vec>, track_count: usize, gap: Spacing, -) -> iced::Element<'a, Message> { +) -> super::common::Element<'a, Message> { let track_count = clamp_track_count(track_count); let gap_px = spacing_to_px(gap); if track_count <= 1 { - let mut col = iced::widget::Column::new() + let mut col = iced_widget::Column::new() .spacing(gap_px) .width(Length::Fill); for item in items { @@ -158,19 +158,19 @@ fn build_grid_template_columns_layout<'a, Message: Clone + 'a>( return col.into(); } - let mut grid_rows = iced::widget::Column::new() + let mut grid_rows = iced_widget::Column::new() .spacing(gap_px) .width(Length::Fill); - let mut current_row = iced::widget::Row::new().spacing(gap_px).width(Length::Fill); + let mut current_row = iced_widget::Row::new().spacing(gap_px).width(Length::Fill); let mut items_in_row = 0_usize; for item in items { - current_row = current_row.push(iced::widget::container(item).width(Length::FillPortion(1))); + current_row = current_row.push(iced_widget::container(item).width(Length::FillPortion(1))); items_in_row += 1; if items_in_row == track_count { grid_rows = grid_rows.push(current_row); - current_row = iced::widget::Row::new().spacing(gap_px).width(Length::Fill); + current_row = iced_widget::Row::new().spacing(gap_px).width(Length::Fill); items_in_row = 0; } } @@ -178,7 +178,7 @@ fn build_grid_template_columns_layout<'a, Message: Clone + 'a>( if items_in_row > 0 { for _ in items_in_row..track_count { current_row = current_row.push( - iced::widget::Space::new() + iced_widget::Space::new() .width(Length::FillPortion(1)) .height(Length::Shrink), ); @@ -191,10 +191,10 @@ fn build_grid_template_columns_layout<'a, Message: Clone + 'a>( /// Create an iced layout for a typed `grid-template-columns` value. pub fn grid_template_columns_layout<'a, Message: Clone + 'a>( - items: Vec>, + items: Vec>, template: GridTemplate, gap: Spacing, -) -> iced::Element<'a, Message> { +) -> super::common::Element<'a, Message> { grid_template_columns_layout_with_context(items, template, gap, None, &[]) } @@ -203,19 +203,19 @@ pub fn grid_template_columns_layout<'a, Message: Clone + 'a>( /// - `inherited_track_count` is used for `Subgrid`. /// - `custom_properties` is used for `CustomProperty`. pub fn grid_template_columns_layout_with_context<'a, Message: Clone + 'a>( - items: Vec>, + items: Vec>, template: GridTemplate, gap: Spacing, inherited_track_count: Option, custom_properties: &[(&str, &str)], -) -> iced::Element<'a, Message> { +) -> super::common::Element<'a, Message> { let track_count = resolve_grid_template_track_count(&template, inherited_track_count, custom_properties); build_grid_template_columns_layout(items, track_count, gap) } -struct ColumnsFlow<'a, Message, Theme = iced_core::Theme, Renderer = iced::Renderer> { - elements: Vec>, +struct ColumnsFlow<'a, Message, Theme = iced_core::Theme, Renderer = iced_widget::Renderer> { + elements: Vec>, columns: Columns, max_columns: usize, gap: f32, @@ -225,7 +225,7 @@ struct ColumnsFlow<'a, Message, Theme = iced_core::Theme, Renderer = iced::Rende impl<'a, Message, Theme, Renderer> ColumnsFlow<'a, Message, Theme, Renderer> { fn with_elements( - elements: Vec>, + elements: Vec>, columns: Columns, ) -> Self { Self { @@ -451,13 +451,13 @@ where } impl<'a, Message, Theme, Renderer> From> - for iced::Element<'a, Message, Theme, Renderer> + for super::common::Element<'a, Message, Theme, Renderer> where Renderer: renderer::Renderer + 'a, Theme: 'a, Message: 'a, { fn from(flow: ColumnsFlow<'a, Message, Theme, Renderer>) -> Self { - iced::Element::new(flow) + super::common::Element::new(flow) } } diff --git a/crates/twill-iced/src/widgets/layout.rs b/crates/twill-iced/src/widgets/layout.rs index 7614828..3396087 100644 --- a/crates/twill-iced/src/widgets/layout.rs +++ b/crates/twill-iced/src/widgets/layout.rs @@ -14,15 +14,18 @@ use iced_core::renderer; use iced_core::widget::{Operation, Tree}; use iced_core::{Clipboard, Shell, Widget as AdvancedWidget}; -struct MarginBox<'a, Message, Theme = iced_core::Theme, Renderer = iced::Renderer> { - child: iced::Element<'a, Message, Theme, Renderer>, +struct MarginBox<'a, Message, Theme = iced_core::Theme, Renderer = iced_widget::Renderer> { + child: super::common::Element<'a, Message, Theme, Renderer>, margin: MarginOffsets, width: Length, height: Length, } impl<'a, Message, Theme, Renderer> MarginBox<'a, Message, Theme, Renderer> { - fn new(child: iced::Element<'a, Message, Theme, Renderer>, margin: MarginOffsets) -> Self { + fn new( + child: super::common::Element<'a, Message, Theme, Renderer>, + margin: MarginOffsets, + ) -> Self { Self { child, margin, @@ -186,22 +189,22 @@ where } impl<'a, Message, Theme, Renderer> From> - for iced::Element<'a, Message, Theme, Renderer> + for super::common::Element<'a, Message, Theme, Renderer> where Renderer: renderer::Renderer + 'a, Theme: 'a, Message: 'a, { fn from(boxed: MarginBox<'a, Message, Theme, Renderer>) -> Self { - iced::Element::new(boxed) + super::common::Element::new(boxed) } } fn apply_margin<'a, Message: Clone + 'a>( - content: iced::Element<'a, Message>, + content: super::common::Element<'a, Message>, margin: twill_core::utilities::Margin, custom_properties: &[(&str, f32)], -) -> iced::Element<'a, Message> { +) -> super::common::Element<'a, Message> { let resolved = to_style_margin(margin, custom_properties); let mut element = content; @@ -260,7 +263,7 @@ fn apply_margin<'a, Message: Clone + 'a>( } if horizontal_auto.is_some() || vertical_auto.is_some() { - let mut wrapper = iced::widget::container(element); + let mut wrapper = iced_widget::container(element); if let Some(horizontal) = horizontal_auto { wrapper = wrapper.width(Length::Fill).align_x(horizontal); @@ -278,9 +281,9 @@ fn apply_margin<'a, Message: Clone + 'a>( /// Apply high-level layout wrappers like Display::Hidden, Overflow, MaxWidth pub fn apply_layout<'a, Message: Clone + 'a>( - content: iced::Element<'a, Message>, + content: super::common::Element<'a, Message>, style: &Style, -) -> iced::Element<'a, Message> { +) -> super::common::Element<'a, Message> { apply_layout_with_custom_properties_and_semantic_theme( content, style, @@ -295,11 +298,11 @@ pub fn apply_layout_with_semantic_theme< Message: Clone + 'a, S: SemanticThemeSource + ?Sized, >( - content: iced::Element<'a, Message>, + content: super::common::Element<'a, Message>, style: &Style, semantic_theme: &S, variant: ThemeVariant, -) -> iced::Element<'a, Message> { +) -> super::common::Element<'a, Message> { apply_layout_with_custom_properties_and_semantic_theme( content, style, @@ -311,10 +314,10 @@ pub fn apply_layout_with_semantic_theme< /// Apply high-level layout wrappers with explicit custom-property values. pub fn apply_layout_with_custom_properties<'a, Message: Clone + 'a>( - content: iced::Element<'a, Message>, + content: super::common::Element<'a, Message>, style: &Style, custom_properties: &[(&str, f32)], -) -> iced::Element<'a, Message> { +) -> super::common::Element<'a, Message> { apply_layout_with_custom_properties_and_semantic_theme( content, style, @@ -329,17 +332,17 @@ fn apply_layout_with_custom_properties_and_semantic_theme< Message: Clone + 'a, S: SemanticThemeSource + ?Sized, >( - content: iced::Element<'a, Message>, + content: super::common::Element<'a, Message>, style: &Style, custom_properties: &[(&str, f32)], semantic_theme: &S, variant: ThemeVariant, -) -> iced::Element<'a, Message> { +) -> super::common::Element<'a, Message> { if matches!( style.display_mode(), Some(twill_core::utilities::Display::Hidden) ) { - return iced::widget::Space::new().into(); + return iced_widget::Space::new().into(); } let mut container = styled_container_with_custom_properties_and_semantic_theme( @@ -416,11 +419,11 @@ fn apply_layout_with_custom_properties_and_semantic_theme< container = container.clip(true); } - let mut element: iced::Element<'a, Message> = if matches!( + let mut element: super::common::Element<'a, Message> = if matches!( style.overflow_value(), Some(twill_core::utilities::Overflow::Auto) | Some(twill_core::utilities::Overflow::Scroll) ) { - iced::widget::scrollable(container).into() + iced_widget::scrollable(container).into() } else { container.into() }; diff --git a/crates/twill-iced/src/widgets/ratio_boxes.rs b/crates/twill-iced/src/widgets/ratio_boxes.rs index a952396..9203442 100644 --- a/crates/twill-iced/src/widgets/ratio_boxes.rs +++ b/crates/twill-iced/src/widgets/ratio_boxes.rs @@ -7,15 +7,23 @@ use iced_core::{Length, Rectangle, Size, Vector, mouse}; use super::common::resolve_aspect_size; -pub(super) struct AspectRatioBox<'a, Message, Theme = iced_core::Theme, Renderer = iced::Renderer> { - child: iced::Element<'a, Message, Theme, Renderer>, +pub(super) struct AspectRatioBox< + 'a, + Message, + Theme = iced_core::Theme, + Renderer = iced_widget::Renderer, +> { + child: super::common::Element<'a, Message, Theme, Renderer>, ratio: f32, width: Length, height: Length, } impl<'a, Message, Theme, Renderer> AspectRatioBox<'a, Message, Theme, Renderer> { - pub(super) fn new(child: iced::Element<'a, Message, Theme, Renderer>, ratio: f32) -> Self { + pub(super) fn new( + child: super::common::Element<'a, Message, Theme, Renderer>, + ratio: f32, + ) -> Self { Self { child, ratio: ratio.max(0.0001), @@ -184,26 +192,34 @@ where } impl<'a, Message, Theme, Renderer> From> - for iced::Element<'a, Message, Theme, Renderer> + for super::common::Element<'a, Message, Theme, Renderer> where Renderer: renderer::Renderer + 'a, Theme: 'a, Message: 'a, { fn from(boxed: AspectRatioBox<'a, Message, Theme, Renderer>) -> Self { - iced::Element::new(boxed) + super::common::Element::new(boxed) } } -pub(super) struct WidthRatioBox<'a, Message, Theme = iced_core::Theme, Renderer = iced::Renderer> { - child: iced::Element<'a, Message, Theme, Renderer>, +pub(super) struct WidthRatioBox< + 'a, + Message, + Theme = iced_core::Theme, + Renderer = iced_widget::Renderer, +> { + child: super::common::Element<'a, Message, Theme, Renderer>, ratio: f32, width: Length, height: Length, } impl<'a, Message, Theme, Renderer> WidthRatioBox<'a, Message, Theme, Renderer> { - pub(super) fn new(child: iced::Element<'a, Message, Theme, Renderer>, ratio: f32) -> Self { + pub(super) fn new( + child: super::common::Element<'a, Message, Theme, Renderer>, + ratio: f32, + ) -> Self { Self { child, ratio: ratio.clamp(0.0, 1.0), @@ -380,26 +396,34 @@ where } impl<'a, Message, Theme, Renderer> From> - for iced::Element<'a, Message, Theme, Renderer> + for super::common::Element<'a, Message, Theme, Renderer> where Renderer: renderer::Renderer + 'a, Theme: 'a, Message: 'a, { fn from(boxed: WidthRatioBox<'a, Message, Theme, Renderer>) -> Self { - iced::Element::new(boxed) + super::common::Element::new(boxed) } } -pub(super) struct HeightRatioBox<'a, Message, Theme = iced_core::Theme, Renderer = iced::Renderer> { - child: iced::Element<'a, Message, Theme, Renderer>, +pub(super) struct HeightRatioBox< + 'a, + Message, + Theme = iced_core::Theme, + Renderer = iced_widget::Renderer, +> { + child: super::common::Element<'a, Message, Theme, Renderer>, ratio: f32, width: Length, height: Length, } impl<'a, Message, Theme, Renderer> HeightRatioBox<'a, Message, Theme, Renderer> { - pub(super) fn new(child: iced::Element<'a, Message, Theme, Renderer>, ratio: f32) -> Self { + pub(super) fn new( + child: super::common::Element<'a, Message, Theme, Renderer>, + ratio: f32, + ) -> Self { Self { child, ratio: ratio.clamp(0.0, 1.0), @@ -576,13 +600,13 @@ where } impl<'a, Message, Theme, Renderer> From> - for iced::Element<'a, Message, Theme, Renderer> + for super::common::Element<'a, Message, Theme, Renderer> where Renderer: renderer::Renderer + 'a, Theme: 'a, Message: 'a, { fn from(boxed: HeightRatioBox<'a, Message, Theme, Renderer>) -> Self { - iced::Element::new(boxed) + super::common::Element::new(boxed) } } diff --git a/crates/twill-iced/src/widgets/tests.rs b/crates/twill-iced/src/widgets/tests.rs index 2d70bff..6a0c0f3 100644 --- a/crates/twill-iced/src/widgets/tests.rs +++ b/crates/twill-iced/src/widgets/tests.rs @@ -523,9 +523,9 @@ fn test_resolve_grid_template_track_count_variants() { #[test] fn test_grid_template_columns_layout_builds() { - let _: iced::Element<'_, ()> = + let _: super::common::Element<'_, ()> = grid_template_columns_layout(vec![], GridTemplate::count(4), Spacing::S4); - let _: iced::Element<'_, ()> = grid_template_columns_layout_with_context( + let _: super::common::Element<'_, ()> = grid_template_columns_layout_with_context( vec![], GridTemplate::subgrid(), Spacing::S2, @@ -577,9 +577,9 @@ fn test_reverse_directions_detection() { #[test] fn test_flex_direction_layout_reverse_builds() { - let _: iced::Element<'_, ()> = + let _: super::common::Element<'_, ()> = flex_direction_layout(vec![], FlexDirection::RowReverse, Spacing::S4); - let _: iced::Element<'_, ()> = + let _: super::common::Element<'_, ()> = flex_direction_layout(vec![], FlexDirection::ColReverse, Spacing::S4); } @@ -601,13 +601,13 @@ fn test_align_items_safe_and_baseline_mapping() { #[test] fn test_align_items_layout_builds() { - let _: iced::Element<'_, ()> = align_items_layout( + let _: super::common::Element<'_, ()> = align_items_layout( vec![], FlexDirection::Row, Spacing::S4, AlignItems::CenterSafe, ); - let _: iced::Element<'_, ()> = align_items_layout( + let _: super::common::Element<'_, ()> = align_items_layout( vec![], FlexDirection::ColReverse, Spacing::S2, @@ -652,9 +652,9 @@ fn test_gap_main_axis_mapping() { #[test] fn test_gap_layout_builds() { - let _: iced::Element<'_, ()> = gap_layout(vec![], FlexDirection::Row, Spacing::S4); - let _: iced::Element<'_, ()> = gap_x_layout(vec![], FlexDirection::Row, Spacing::S6); - let _: iced::Element<'_, ()> = gap_y_layout(vec![], FlexDirection::Col, Spacing::S3); + let _: super::common::Element<'_, ()> = gap_layout(vec![], FlexDirection::Row, Spacing::S4); + let _: super::common::Element<'_, ()> = gap_x_layout(vec![], FlexDirection::Row, Spacing::S6); + let _: super::common::Element<'_, ()> = gap_y_layout(vec![], FlexDirection::Col, Spacing::S3); } #[test] @@ -675,19 +675,19 @@ fn test_justify_content_safe_mapping() { #[test] fn test_justify_content_layout_builds() { - let _: iced::Element<'_, ()> = justify_content_layout( + let _: super::common::Element<'_, ()> = justify_content_layout( vec![], FlexDirection::Row, Spacing::S4, JustifyContent::Between, ); - let _: iced::Element<'_, ()> = justify_content_layout( + let _: super::common::Element<'_, ()> = justify_content_layout( vec![], FlexDirection::RowReverse, Spacing::S2, JustifyContent::CenterSafe, ); - let _: iced::Element<'_, ()> = justify_content_layout( + let _: super::common::Element<'_, ()> = justify_content_layout( vec![], FlexDirection::ColReverse, Spacing::S2, From 16c8afb14fe70fde8f1f7f83365db4ae300482c9 Mon Sep 17 00:00:00 2001 From: FerrisMind Date: Sun, 26 Jul 2026 16:06:25 +0400 Subject: [PATCH 5/5] Add 'wgpu' feature to iced_widget dependency --- crates/twill-iced/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/twill-iced/Cargo.toml b/crates/twill-iced/Cargo.toml index 69d895f..8d723b4 100644 --- a/crates/twill-iced/Cargo.toml +++ b/crates/twill-iced/Cargo.toml @@ -16,7 +16,7 @@ categories = ["gui", "rendering"] twill-core = { path = "../twill-core", version = "0.3.0" } twill-backend-common = { path = "../twill-backend-common", version = "0.3.0" } iced_core = "0.14" -iced_widget = { version = "0.14", features = ["canvas"] } +iced_widget = { version = "0.14", features = ["canvas", "wgpu"] } [package.metadata.docs.rs] rustdoc-args = ["--cfg", "docsrs"]