chore: add the rounded rectangle strip helper

This commit is contained in:
Ashley Wulber 2026-06-30 11:06:41 -04:00 committed by Ashley Wulber
parent a365d45091
commit bb0145c566
3 changed files with 89 additions and 1 deletions

View file

@ -0,0 +1,86 @@
use iced::Rectangle;
use iced_runtime::platform_specific::wayland::CornerRadius;
#[must_use]
pub fn rounded_rect_strips(rect: Rectangle<f32>, radius: CornerRadius) -> Vec<Rectangle<f32>> {
let mut out = Vec::new();
let w = rect.width.max(0.0);
let h = rect.height.max(0.0);
if w <= 0.0 || h <= 0.0 {
return out;
}
let tl = radius.top_left as i32;
let tr = radius.top_right as i32;
let bl = radius.bottom_left as i32;
let br = radius.bottom_right as i32;
let max_top = tl.max(tr);
let max_bottom = bl.max(br);
let center_y = rect.y + max_top as f32;
let center_h = (h as i32 - max_top - max_bottom).max(0) as f32;
if center_h > 0.0 {
out.push(Rectangle {
x: rect.x,
y: center_y,
width: w,
height: center_h,
});
}
for y in 0..max_top {
let left = if y < tl { circle_inset(tl, y) } else { 0 };
let right = if y < tr { circle_inset(tr, y) } else { 0 };
let strip_x = rect.x + left as f32;
let strip_w = (w as i32 - left - right).max(0) as f32;
if strip_w > 0.0 {
out.push(Rectangle {
x: strip_x,
y: rect.y + y as f32,
width: strip_w,
height: 1.0,
});
}
}
for y in 0..max_bottom {
let cy = max_bottom - 1 - y;
let left = if cy < bl { circle_inset(bl, cy) } else { 0 };
let right = if cy < br { circle_inset(br, cy) } else { 0 };
let strip_x = rect.x + left as f32;
let strip_w = (w as i32 - left - right).max(0) as f32;
if strip_w > 0.0 {
out.push(Rectangle {
x: strip_x,
y: rect.y + h - max_bottom as f32 + y as f32,
width: strip_w,
height: 1.0,
});
}
}
out
}
fn circle_inset(radius: i32, y: i32) -> i32 {
if radius <= 0 {
return 0;
}
let fy = y as f32 + 0.5;
let r = radius as f32;
let x = r - (r * r - (r - fy) * (r - fy)).sqrt();
x.floor() as i32
}

View file

@ -2,6 +2,8 @@
// SPDX-License-Identifier: MPL-2.0
pub mod action;
#[cfg(all(feature = "wayland", target_os = "linux"))]
pub mod corner_radius;
use iced::{Limits, Size, Task};
use std::any::Any;

View file

@ -488,7 +488,7 @@ impl<'a, Message: 'a + Clone> Widget<Message, crate::Theme, crate::Renderer>
None => {
styling.border_radius = theme.cosmic().radius_0().into();
}
};
}
}
let mut icon_color = styling.icon_color.unwrap_or(renderer_style.icon_color);