Implemented `tile_origin` for gradients.
Fixed checkerboard.
This commit is contained in:
parent
6cabab4d5a
commit
2ec2db72b3
|
@ -1653,6 +1653,7 @@ impl FrameBuilder {
|
|||
line: PxLine,
|
||||
stops: &[RenderGradientStop],
|
||||
extend_mode: RenderExtendMode,
|
||||
tile_origin: PxPoint,
|
||||
tile_size: PxSize,
|
||||
tile_spacing: PxSize,
|
||||
) {
|
||||
|
@ -1675,6 +1676,7 @@ impl FrameBuilder {
|
|||
extend_mode,
|
||||
},
|
||||
stops,
|
||||
tile_origin,
|
||||
tile_size,
|
||||
tile_spacing,
|
||||
);
|
||||
|
@ -1703,6 +1705,7 @@ impl FrameBuilder {
|
|||
radius: PxSize,
|
||||
stops: &[RenderGradientStop],
|
||||
extend_mode: RenderExtendMode,
|
||||
tile_origin: PxPoint,
|
||||
tile_size: PxSize,
|
||||
tile_spacing: PxSize,
|
||||
) {
|
||||
|
@ -1727,6 +1730,7 @@ impl FrameBuilder {
|
|||
extend_mode,
|
||||
},
|
||||
stops,
|
||||
tile_origin,
|
||||
tile_size,
|
||||
tile_spacing,
|
||||
);
|
||||
|
@ -1752,6 +1756,7 @@ impl FrameBuilder {
|
|||
angle: AngleRadian,
|
||||
stops: &[RenderGradientStop],
|
||||
extend_mode: RenderExtendMode,
|
||||
tile_origin: PxPoint,
|
||||
tile_size: PxSize,
|
||||
tile_spacing: PxSize,
|
||||
) {
|
||||
|
@ -1776,6 +1781,7 @@ impl FrameBuilder {
|
|||
extend_mode,
|
||||
},
|
||||
stops,
|
||||
tile_origin,
|
||||
tile_size,
|
||||
tile_spacing,
|
||||
);
|
||||
|
@ -1876,8 +1882,14 @@ impl FrameBuilder {
|
|||
|
||||
let offset = offset - radius.to_vector();
|
||||
|
||||
self.display_list
|
||||
.push_radial_gradient(PxRect::new(offset, bounds), gradient, &stops, bounds, PxSize::zero());
|
||||
self.display_list.push_radial_gradient(
|
||||
PxRect::new(offset, bounds),
|
||||
gradient,
|
||||
&stops,
|
||||
PxPoint::zero(),
|
||||
bounds,
|
||||
PxSize::zero(),
|
||||
);
|
||||
}
|
||||
|
||||
/// Push a custom display extension context with custom encoding.
|
||||
|
|
|
@ -1271,6 +1271,21 @@ impl_from_and_into_var! {
|
|||
light: light.into(),
|
||||
}
|
||||
}
|
||||
|
||||
/// From same color to both.
|
||||
fn from(color: Rgba) -> ColorPair {
|
||||
ColorPair { dark: color, light: color }
|
||||
}
|
||||
|
||||
/// From same color to both.
|
||||
fn from(color: Hsva) -> ColorPair {
|
||||
Rgba::from(color).into()
|
||||
}
|
||||
|
||||
/// From same color to both.
|
||||
fn from(color: Hsla) -> ColorPair {
|
||||
Rgba::from(color).into()
|
||||
}
|
||||
}
|
||||
impl ColorPair {
|
||||
/// Overlay white with `highlight` amount as alpha over the [`dark`] color.
|
||||
|
@ -1286,6 +1301,14 @@ impl ColorPair {
|
|||
pub fn highlight_light(self, hightlight: impl Into<Factor>) -> Rgba {
|
||||
colors::BLACK.with_alpha(hightlight.into()).mix_normal(self.light)
|
||||
}
|
||||
|
||||
/// Gets the color for the scheme.
|
||||
pub fn color(self, scheme: ColorScheme) -> Rgba {
|
||||
match scheme {
|
||||
ColorScheme::Light => self.light,
|
||||
ColorScheme::Dark => self.dark,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Defines the color space for color interpolation in a context.
|
||||
|
|
|
@ -213,6 +213,21 @@ macro_rules! __impl_from_and_into_var {
|
|||
$($rest)+
|
||||
}
|
||||
};
|
||||
// INPUT ARRAY:
|
||||
(
|
||||
=input=>
|
||||
[$($config:tt)*]
|
||||
([ $($destruct:tt)+ ] : $Input:ty) $($rest:tt)+
|
||||
) => {
|
||||
$crate::__impl_from_and_into_var! {
|
||||
=output=>
|
||||
[
|
||||
input_type { $Input }
|
||||
$($config)*
|
||||
]
|
||||
$($rest)+
|
||||
}
|
||||
};
|
||||
|
||||
// OUTPUT (without From):
|
||||
(
|
||||
|
|
|
@ -363,6 +363,7 @@ impl DisplayListBuilder {
|
|||
clip_rect: PxRect,
|
||||
gradient: wr::Gradient,
|
||||
stops: &[wr::GradientStop],
|
||||
tile_origin: PxPoint,
|
||||
tile_size: PxSize,
|
||||
tile_spacing: PxSize,
|
||||
) {
|
||||
|
@ -370,6 +371,7 @@ impl DisplayListBuilder {
|
|||
clip_rect,
|
||||
gradient,
|
||||
stops: stops.to_vec().into_boxed_slice(),
|
||||
tile_origin,
|
||||
tile_size,
|
||||
tile_spacing,
|
||||
})
|
||||
|
@ -381,6 +383,7 @@ impl DisplayListBuilder {
|
|||
clip_rect: PxRect,
|
||||
gradient: wr::RadialGradient,
|
||||
stops: &[wr::GradientStop],
|
||||
tile_origin: PxPoint,
|
||||
tile_size: PxSize,
|
||||
tile_spacing: PxSize,
|
||||
) {
|
||||
|
@ -388,6 +391,7 @@ impl DisplayListBuilder {
|
|||
clip_rect,
|
||||
gradient,
|
||||
stops: stops.to_vec().into_boxed_slice(),
|
||||
tile_origin,
|
||||
tile_size,
|
||||
tile_spacing,
|
||||
});
|
||||
|
@ -399,6 +403,7 @@ impl DisplayListBuilder {
|
|||
clip_rect: PxRect,
|
||||
gradient: wr::ConicGradient,
|
||||
stops: &[wr::GradientStop],
|
||||
tile_origin: PxPoint,
|
||||
tile_size: PxSize,
|
||||
tile_spacing: PxSize,
|
||||
) {
|
||||
|
@ -406,6 +411,7 @@ impl DisplayListBuilder {
|
|||
clip_rect,
|
||||
gradient,
|
||||
stops: stops.to_vec().into_boxed_slice(),
|
||||
tile_origin,
|
||||
tile_size,
|
||||
tile_spacing,
|
||||
});
|
||||
|
@ -1147,6 +1153,7 @@ enum DisplayItem {
|
|||
clip_rect: PxRect,
|
||||
gradient: wr::Gradient,
|
||||
stops: Box<[wr::GradientStop]>,
|
||||
tile_origin: PxPoint,
|
||||
tile_size: PxSize,
|
||||
tile_spacing: PxSize,
|
||||
},
|
||||
|
@ -1154,6 +1161,7 @@ enum DisplayItem {
|
|||
clip_rect: PxRect,
|
||||
gradient: wr::RadialGradient,
|
||||
stops: Box<[wr::GradientStop]>,
|
||||
tile_origin: PxPoint,
|
||||
tile_size: PxSize,
|
||||
tile_spacing: PxSize,
|
||||
},
|
||||
|
@ -1161,6 +1169,7 @@ enum DisplayItem {
|
|||
clip_rect: PxRect,
|
||||
gradient: wr::ConicGradient,
|
||||
stops: Box<[wr::GradientStop]>,
|
||||
tile_origin: PxPoint,
|
||||
tile_size: PxSize,
|
||||
tile_spacing: PxSize,
|
||||
},
|
||||
|
@ -1494,17 +1503,21 @@ impl DisplayItem {
|
|||
clip_rect,
|
||||
gradient,
|
||||
stops,
|
||||
mut tile_origin,
|
||||
tile_size,
|
||||
tile_spacing,
|
||||
} => {
|
||||
tile_origin.x.0 = tile_origin.x.0.rem_euclid(tile_size.width.0);
|
||||
tile_origin.y.0 = tile_origin.y.0.rem_euclid(tile_size.height.0);
|
||||
let bounds = PxRect::new(-tile_origin, clip_rect.size + tile_origin.to_vector().to_size()).to_wr();
|
||||
|
||||
let clip = sc.clip_chain_id(wr_list);
|
||||
let bounds = clip_rect.to_wr();
|
||||
// stops needs to immediately followed by the gradient, if the clip-chain item
|
||||
// is inserted in the between the stops are lost.
|
||||
wr_list.push_stops(stops);
|
||||
wr_list.push_gradient(
|
||||
&wr::CommonItemProperties {
|
||||
clip_rect: bounds,
|
||||
clip_rect: clip_rect.to_wr(),
|
||||
clip_chain_id: clip,
|
||||
spatial_id: sc.spatial_id(),
|
||||
flags: sc.primitive_flags(),
|
||||
|
@ -1519,15 +1532,19 @@ impl DisplayItem {
|
|||
clip_rect,
|
||||
gradient,
|
||||
stops,
|
||||
mut tile_origin,
|
||||
tile_size,
|
||||
tile_spacing,
|
||||
} => {
|
||||
tile_origin.x.0 = tile_origin.x.0.rem_euclid(tile_size.width.0);
|
||||
tile_origin.y.0 = tile_origin.y.0.rem_euclid(tile_size.height.0);
|
||||
let bounds = PxRect::new(-tile_origin, clip_rect.size + tile_origin.to_vector().to_size()).to_wr();
|
||||
|
||||
let clip = sc.clip_chain_id(wr_list);
|
||||
let bounds = clip_rect.to_wr();
|
||||
wr_list.push_stops(stops);
|
||||
wr_list.push_radial_gradient(
|
||||
&wr::CommonItemProperties {
|
||||
clip_rect: bounds,
|
||||
clip_rect: clip_rect.to_wr(),
|
||||
clip_chain_id: clip,
|
||||
spatial_id: sc.spatial_id(),
|
||||
flags: sc.primitive_flags(),
|
||||
|
@ -1542,15 +1559,19 @@ impl DisplayItem {
|
|||
clip_rect,
|
||||
gradient,
|
||||
stops,
|
||||
mut tile_origin,
|
||||
tile_size,
|
||||
tile_spacing,
|
||||
} => {
|
||||
tile_origin.x.0 = tile_origin.x.0.rem_euclid(tile_size.width.0);
|
||||
tile_origin.y.0 = tile_origin.y.0.rem_euclid(tile_size.height.0);
|
||||
let bounds = PxRect::new(-tile_origin, clip_rect.size + tile_origin.to_vector().to_size()).to_wr();
|
||||
|
||||
let clip = sc.clip_chain_id(wr_list);
|
||||
let bounds = clip_rect.to_wr();
|
||||
wr_list.push_stops(stops);
|
||||
wr_list.push_conic_gradient(
|
||||
&wr::CommonItemProperties {
|
||||
clip_rect: bounds,
|
||||
clip_rect: clip_rect.to_wr(),
|
||||
clip_chain_id: clip,
|
||||
spatial_id: sc.spatial_id(),
|
||||
flags: sc.primitive_flags(),
|
||||
|
|
|
@ -221,7 +221,7 @@ pub fn default_cmd_tooltip_fn(args: CmdTooltipArgs) -> impl UiNode {
|
|||
/// When this is set the button widget sets these properties if they are not set:
|
||||
///
|
||||
/// * [`child`]: Set to an widget produced by [`cmd_child_fn`](fn@cmd_child_fn), by default is `Text!(cmd.name())`.
|
||||
/// * [`tooltip_fn`]: Set to a widget function provided by [`cmd_tooltip_fn`](fn@cmd_tooltip_fn), by default it
|
||||
/// * [`tooltip_fn`]: Set to a widget function provided by [`cmd_tooltip_fn`](fn@cmd_tooltip_fn), by default it
|
||||
/// shows the command info and first shortcut.
|
||||
/// * [`enabled`]: Set to `cmd.is_enabled()`.
|
||||
/// * [`visibility`]: Set to `cmd.has_handlers().into()`.
|
||||
|
|
|
@ -6,4 +6,6 @@ edition = "2021"
|
|||
license = "Apache-2.0"
|
||||
|
||||
[dependencies]
|
||||
zero-ui-wgt = { path = "../zero-ui-wgt" }
|
||||
zero-ui-wgt = { path = "../zero-ui-wgt" }
|
||||
zero-ui-color = { path = "../zero-ui-color" }
|
||||
serde = "1"
|
|
@ -3,10 +3,14 @@
|
|||
|
||||
//! Checkerboard widget, properties and nodes.
|
||||
|
||||
use std::ops;
|
||||
|
||||
use zero_ui_color::COLOR_SCHEME_VAR;
|
||||
use zero_ui_wgt::prelude::{
|
||||
gradient::{RenderExtendMode, RenderGradientStop},
|
||||
*,
|
||||
};
|
||||
|
||||
/// A checkerboard visual.
|
||||
///
|
||||
/// This widget draws a checkerboard pattern, with configurable dimensions and colors.
|
||||
|
@ -18,51 +22,72 @@ impl Checkerboard {
|
|||
}
|
||||
}
|
||||
|
||||
/// Checker board colors.
|
||||
///
|
||||
/// See [`colors`](fn@colors) for more details.
|
||||
#[derive(Debug, Clone, PartialEq, Hash, serde::Serialize, serde::Deserialize)]
|
||||
pub struct Colors(pub [ColorPair; 2]);
|
||||
impl ops::Deref for Colors {
|
||||
type Target = [ColorPair; 2];
|
||||
|
||||
fn deref(&self) -> &Self::Target {
|
||||
&self.0
|
||||
}
|
||||
}
|
||||
impl_from_and_into_var! {
|
||||
fn from<C: Into<ColorPair>>([c0, c1]: [C; 2]) -> Colors {
|
||||
Colors([c0.into(), c1.into()])
|
||||
}
|
||||
fn from<C0: Into<ColorPair>, C1: Into<ColorPair>>((c0, c1): (C0, C1)) -> Colors {
|
||||
Colors([c0.into(), c1.into()])
|
||||
}
|
||||
}
|
||||
|
||||
context_var! {
|
||||
/// The checkerboard colors.
|
||||
///
|
||||
/// Default depends on the color scheme.
|
||||
///
|
||||
/// [`BLACK`]: colors::BLACK
|
||||
/// [`WHITE`]: colors::WHITE
|
||||
pub static COLORS_VAR: (Rgba, Rgba) = color_scheme_map(
|
||||
(rgb(20, 20, 20), rgb(40, 40, 40)),
|
||||
(rgb(202, 202, 204), rgb(253, 253, 253))
|
||||
);
|
||||
|
||||
/// The size of one color rectangle in the checkerboard.
|
||||
///
|
||||
/// Default is `(20, 20)`.
|
||||
pub static SIZE_VAR: Size = (20, 20);
|
||||
pub static COLORS_VAR: Colors = [
|
||||
ColorPair { dark: rgb(20, 20, 20), light: rgb(202, 202, 204) },
|
||||
ColorPair { dark: rgb(40, 40, 40), light: rgb(253, 253, 253) },
|
||||
];
|
||||
|
||||
/// Offset applied to the checkerboard pattern.
|
||||
///
|
||||
/// Default is no offset `(0, 0)`.
|
||||
pub static OFFSET_VAR: Vector = Vector::zero();
|
||||
pub static ORIGIN_VAR: Point = Point::zero();
|
||||
|
||||
/// The size of one color rectangle in the checkerboard.
|
||||
///
|
||||
/// Default is `(20, 20)`.
|
||||
pub static SIZE_VAR: Size = 20;
|
||||
}
|
||||
|
||||
/// Set both checkerboard colors.
|
||||
///
|
||||
/// The values are the interchanging colors for a given color scheme, for example in the dark
|
||||
/// color scheme the `(colors.0.dark, colors.1.dark)` colors are used.
|
||||
///
|
||||
/// This property sets [`COLORS_VAR`] for all inner checkerboard widgets.
|
||||
#[property(CONTEXT, default(COLORS_VAR))]
|
||||
pub fn colors(child: impl UiNode, colors: impl IntoVar<(Rgba, Rgba)>) -> impl UiNode {
|
||||
#[property(CONTEXT, default(COLORS_VAR), widget_impl(Checkerboard))]
|
||||
pub fn colors(child: impl UiNode, colors: impl IntoVar<Colors>) -> impl UiNode {
|
||||
with_context_var(child, COLORS_VAR, colors)
|
||||
}
|
||||
|
||||
/// Set the size of a checkerboard color rectangle.
|
||||
///
|
||||
/// This property sets the [`SIZE_VAR`] for all inner checkerboard widgets.
|
||||
#[property(CONTEXT, default(SIZE_VAR))]
|
||||
#[property(CONTEXT, default(SIZE_VAR), widget_impl(Checkerboard))]
|
||||
pub fn cb_size(child: impl UiNode, size: impl IntoVar<Size>) -> impl UiNode {
|
||||
with_context_var(child, SIZE_VAR, size)
|
||||
}
|
||||
|
||||
/// Sets the offset of the checkerboard pattern.
|
||||
///
|
||||
/// Relative values are resolved in the context of a [`cb_size`](fn@cb_size).
|
||||
///
|
||||
/// This property sets the [`OFFSET_VAR`] for all inner checkerboard widgets.
|
||||
#[property(CONTEXT, default(OFFSET_VAR))]
|
||||
pub fn cb_offset(child: impl UiNode, offset: impl IntoVar<Vector>) -> impl UiNode {
|
||||
with_context_var(child, OFFSET_VAR, offset)
|
||||
#[property(CONTEXT, default(ORIGIN_VAR), widget_impl(Checkerboard))]
|
||||
pub fn cb_origin(child: impl UiNode, offset: impl IntoVar<Point>) -> impl UiNode {
|
||||
with_context_var(child, ORIGIN_VAR, offset)
|
||||
}
|
||||
|
||||
/// Checkerboard node.
|
||||
|
@ -70,15 +95,16 @@ pub fn cb_offset(child: impl UiNode, offset: impl IntoVar<Vector>) -> impl UiNod
|
|||
/// The node is configured by the contextual variables defined in the widget.
|
||||
pub fn node() -> impl UiNode {
|
||||
let mut render_size = PxSize::zero();
|
||||
let mut tile_origin = PxPoint::zero();
|
||||
let mut tile_size = PxSize::zero();
|
||||
let mut center = PxPoint::zero();
|
||||
|
||||
match_node_leaf(move |op| match op {
|
||||
UiNodeOp::Init => {
|
||||
WIDGET
|
||||
.sub_var_render(&COLORS_VAR)
|
||||
.sub_var_render(&COLOR_SCHEME_VAR)
|
||||
.sub_var_layout(&SIZE_VAR)
|
||||
.sub_var_layout(&OFFSET_VAR);
|
||||
.sub_var_layout(&ORIGIN_VAR);
|
||||
}
|
||||
UiNodeOp::Measure { desired_size, .. } => {
|
||||
*desired_size = LAYOUT.constraints().fill_size();
|
||||
|
@ -91,31 +117,23 @@ pub fn node() -> impl UiNode {
|
|||
}
|
||||
|
||||
let ts = SIZE_VAR.layout_dft(PxSize::splat(Px(4)));
|
||||
let to = LAYOUT.with_constraints(PxConstraints2d::new_exact_size(ts), || ORIGIN_VAR.layout());
|
||||
|
||||
let mut offset = OFFSET_VAR.layout();
|
||||
if offset.x > ts.width {
|
||||
offset.x /= ts.width;
|
||||
}
|
||||
if offset.y > ts.height {
|
||||
offset.y /= ts.height;
|
||||
}
|
||||
|
||||
let mut c = ts.to_vector().to_point() / 2.0.fct();
|
||||
c += offset;
|
||||
|
||||
if tile_size != ts || center != c {
|
||||
if tile_origin != to || tile_size != ts {
|
||||
tile_origin = to;
|
||||
tile_size = ts;
|
||||
center = c;
|
||||
|
||||
WIDGET.render();
|
||||
}
|
||||
}
|
||||
UiNodeOp::Render { frame } => {
|
||||
let (c0, c1) = COLORS_VAR.get();
|
||||
let colors = [c0.into(), c1.into()];
|
||||
let [c0, c1] = COLORS_VAR.get().0;
|
||||
let sch = COLOR_SCHEME_VAR.get();
|
||||
let colors = [c0.color(sch).into(), c1.color(sch).into()];
|
||||
|
||||
frame.push_conic_gradient(
|
||||
PxRect::from_size(render_size),
|
||||
center,
|
||||
tile_size.to_vector().to_point() / 2.fct(),
|
||||
0.rad(),
|
||||
&[
|
||||
RenderGradientStop {
|
||||
|
@ -152,6 +170,7 @@ pub fn node() -> impl UiNode {
|
|||
},
|
||||
],
|
||||
RenderExtendMode::Repeat,
|
||||
tile_origin,
|
||||
tile_size,
|
||||
PxSize::zero(),
|
||||
);
|
||||
|
|
|
@ -155,7 +155,7 @@ where
|
|||
}
|
||||
|
||||
/// Continue building a tiled linear gradient.
|
||||
pub fn tile<T, TS>(self, tile_size: T, tile_spacing: TS) -> TiledLinearGradient<S, A, E, T::Var, TS::Var>
|
||||
pub fn tile<T, TS>(self, tile_size: T, tile_spacing: TS) -> TiledLinearGradient<S, A, E, LocalVar<Point>, T::Var, TS::Var>
|
||||
where
|
||||
T: IntoVar<Size>,
|
||||
TS: IntoVar<Size>,
|
||||
|
@ -164,6 +164,7 @@ where
|
|||
stops: self.stops,
|
||||
axis: self.axis,
|
||||
extend_mode: self.extend_mode,
|
||||
tile_origin: LocalVar(Point::zero()),
|
||||
tile_size: tile_size.into_var(),
|
||||
tile_spacing: tile_spacing.into_var(),
|
||||
data: self.data,
|
||||
|
@ -175,7 +176,7 @@ where
|
|||
///
|
||||
/// Relative values are resolved on the full available size, so settings this to `100.pct()` is
|
||||
/// the same as not tiling.
|
||||
pub fn tile_size<T>(self, size: T) -> TiledLinearGradient<S, A, E, T::Var, LocalVar<Size>>
|
||||
pub fn tile_size<T>(self, size: T) -> TiledLinearGradient<S, A, E, LocalVar<Point>, T::Var, LocalVar<Size>>
|
||||
where
|
||||
T: IntoVar<Size>,
|
||||
{
|
||||
|
@ -192,20 +193,22 @@ where
|
|||
/// Use [`gradient`], [`linear_gradient`] to build.
|
||||
///
|
||||
/// [`gradient`]: fn@gradient
|
||||
pub struct TiledLinearGradient<S, A, E, T, TS> {
|
||||
pub struct TiledLinearGradient<S, A, E, O, T, TS> {
|
||||
stops: S,
|
||||
axis: A,
|
||||
extend_mode: E,
|
||||
tile_origin: O,
|
||||
tile_size: T,
|
||||
tile_spacing: TS,
|
||||
data: LinearNodeData,
|
||||
tile_data: TiledNodeData,
|
||||
}
|
||||
impl<S, A, E, T, TS> TiledLinearGradient<S, A, E, T, TS>
|
||||
impl<S, A, E, O, T, TS> TiledLinearGradient<S, A, E, O, T, TS>
|
||||
where
|
||||
S: Var<GradientStops>,
|
||||
A: Var<LinearGradientAxis>,
|
||||
E: Var<ExtendMode>,
|
||||
O: Var<Point>,
|
||||
T: Var<Size>,
|
||||
TS: Var<Size>,
|
||||
{
|
||||
|
@ -218,7 +221,7 @@ where
|
|||
/// fully fit in the available space, so setting this to `1.lft()` will cause the *border* tiles
|
||||
/// to always touch the full bounds and the middle filled with the maximum full tiles that fit or
|
||||
/// empty space.
|
||||
pub fn tile_spacing<TS2>(self, spacing: TS2) -> TiledLinearGradient<S, A, E, T::Var, TS2::Var>
|
||||
pub fn tile_spacing<TS2>(self, spacing: TS2) -> TiledLinearGradient<S, A, E, O, T, TS2::Var>
|
||||
where
|
||||
TS2: IntoVar<Size>,
|
||||
{
|
||||
|
@ -226,12 +229,33 @@ where
|
|||
stops: self.stops,
|
||||
axis: self.axis,
|
||||
extend_mode: self.extend_mode,
|
||||
tile_origin: self.tile_origin,
|
||||
tile_size: self.tile_size,
|
||||
tile_spacing: spacing.into_var(),
|
||||
data: self.data,
|
||||
tile_data: self.tile_data,
|
||||
}
|
||||
}
|
||||
|
||||
/// Sets the tile offset.
|
||||
///
|
||||
/// Relative values are resolved on the tile size, so setting this to `100.pct()` will
|
||||
/// offset a full *turn*.
|
||||
pub fn tile_origin<O2>(self, origin: O2) -> TiledLinearGradient<S, A, E, O2::Var, T, TS>
|
||||
where
|
||||
O2: IntoVar<Point>,
|
||||
{
|
||||
TiledLinearGradient {
|
||||
stops: self.stops,
|
||||
axis: self.axis,
|
||||
extend_mode: self.extend_mode,
|
||||
tile_origin: origin.into_var(),
|
||||
tile_size: self.tile_size,
|
||||
tile_spacing: self.tile_spacing,
|
||||
data: self.data,
|
||||
tile_data: self.tile_data,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Radial gradient.
|
||||
|
@ -281,7 +305,7 @@ where
|
|||
}
|
||||
|
||||
/// Continue building a tiled radial gradient.
|
||||
pub fn tile<T, TS>(self, tile_size: T, tile_spacing: TS) -> TiledRadialGradient<S, C, R, E, T::Var, TS::Var>
|
||||
pub fn tile<T, TS>(self, tile_size: T, tile_spacing: TS) -> TiledRadialGradient<S, C, R, E, LocalVar<Point>, T::Var, TS::Var>
|
||||
where
|
||||
T: IntoVar<Size>,
|
||||
TS: IntoVar<Size>,
|
||||
|
@ -291,6 +315,7 @@ where
|
|||
center: self.center,
|
||||
radius: self.radius,
|
||||
extend_mode: self.extend_mode,
|
||||
tile_origin: LocalVar(Point::zero()),
|
||||
tile_size: tile_size.into_var(),
|
||||
tile_spacing: tile_spacing.into_var(),
|
||||
data: self.data,
|
||||
|
@ -299,7 +324,7 @@ where
|
|||
}
|
||||
|
||||
/// Continue building a tiled radial gradient.
|
||||
pub fn tile_size<T>(self, size: T) -> TiledRadialGradient<S, C, R, E, T::Var, LocalVar<Size>>
|
||||
pub fn tile_size<T>(self, size: T) -> TiledRadialGradient<S, C, R, E, LocalVar<Point>, T::Var, LocalVar<Size>>
|
||||
where
|
||||
T: IntoVar<Size>,
|
||||
{
|
||||
|
@ -315,22 +340,24 @@ where
|
|||
/// Use [`gradient`], [`radial_gradient`] to build.
|
||||
///
|
||||
/// [`gradient`]: fn@gradient
|
||||
pub struct TiledRadialGradient<S, C, R, E, T, TS> {
|
||||
pub struct TiledRadialGradient<S, C, R, E, O, T, TS> {
|
||||
stops: S,
|
||||
center: C,
|
||||
radius: R,
|
||||
extend_mode: E,
|
||||
tile_origin: O,
|
||||
tile_size: T,
|
||||
tile_spacing: TS,
|
||||
data: RadialNodeData,
|
||||
tile_data: TiledNodeData,
|
||||
}
|
||||
impl<S, C, R, E, T, TS> TiledRadialGradient<S, C, R, E, T, TS>
|
||||
impl<S, C, R, E, O, T, TS> TiledRadialGradient<S, C, R, E, O, T, TS>
|
||||
where
|
||||
S: Var<GradientStops>,
|
||||
C: Var<Point>,
|
||||
R: Var<GradientRadius>,
|
||||
E: Var<ExtendMode>,
|
||||
O: Var<Point>,
|
||||
T: Var<Size>,
|
||||
TS: Var<Size>,
|
||||
{
|
||||
|
@ -343,7 +370,7 @@ where
|
|||
/// fully fit in the available space, so setting this to `1.lft()` will cause the *border* tiles
|
||||
/// to always touch the full bounds and the middle filled with the maximum full tiles that fit or
|
||||
/// empty space.
|
||||
pub fn tile_spacing<TS2>(self, spacing: TS2) -> TiledRadialGradient<S, C, R, E, T::Var, TS2::Var>
|
||||
pub fn tile_spacing<TS2>(self, spacing: TS2) -> TiledRadialGradient<S, C, R, E, O, T, TS2::Var>
|
||||
where
|
||||
TS2: IntoVar<Size>,
|
||||
{
|
||||
|
@ -352,12 +379,34 @@ where
|
|||
center: self.center,
|
||||
radius: self.radius,
|
||||
extend_mode: self.extend_mode,
|
||||
tile_origin: self.tile_origin,
|
||||
tile_size: self.tile_size,
|
||||
tile_spacing: spacing.into_var(),
|
||||
data: self.data,
|
||||
tile_data: self.tile_data,
|
||||
}
|
||||
}
|
||||
|
||||
/// Sets the tile offset.
|
||||
///
|
||||
/// Relative values are resolved on the tile size, so setting this to `100.pct()` will
|
||||
/// offset a full *turn*.
|
||||
pub fn tile_origin<O2>(self, origin: O2) -> TiledRadialGradient<S, C, R, E, O2::Var, T, TS>
|
||||
where
|
||||
O2: IntoVar<Point>,
|
||||
{
|
||||
TiledRadialGradient {
|
||||
stops: self.stops,
|
||||
center: self.center,
|
||||
radius: self.radius,
|
||||
extend_mode: self.extend_mode,
|
||||
tile_origin: origin.into_var(),
|
||||
tile_size: self.tile_size,
|
||||
tile_spacing: self.tile_spacing,
|
||||
data: self.data,
|
||||
tile_data: self.tile_data,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Conic gradient.
|
||||
|
@ -407,7 +456,7 @@ where
|
|||
}
|
||||
|
||||
/// Continue building a tiled radial gradient.
|
||||
pub fn tile<T, TS>(self, tile_size: T, tile_spacing: TS) -> TiledConicGradient<S, C, A, E, T::Var, TS::Var>
|
||||
pub fn tile<T, TS>(self, tile_size: T, tile_spacing: TS) -> TiledConicGradient<S, C, A, E, LocalVar<Point>, T::Var, TS::Var>
|
||||
where
|
||||
T: IntoVar<Size>,
|
||||
TS: IntoVar<Size>,
|
||||
|
@ -417,6 +466,7 @@ where
|
|||
center: self.center,
|
||||
angle: self.angle,
|
||||
extend_mode: self.extend_mode,
|
||||
tile_origin: LocalVar(Point::zero()),
|
||||
tile_size: tile_size.into_var(),
|
||||
tile_spacing: tile_spacing.into_var(),
|
||||
data: self.data,
|
||||
|
@ -425,7 +475,7 @@ where
|
|||
}
|
||||
|
||||
/// Continue building a tiled radial gradient.
|
||||
pub fn tile_size<T>(self, size: T) -> TiledConicGradient<S, C, A, E, T::Var, LocalVar<Size>>
|
||||
pub fn tile_size<T>(self, size: T) -> TiledConicGradient<S, C, A, E, LocalVar<Point>, T::Var, LocalVar<Size>>
|
||||
where
|
||||
T: IntoVar<Size>,
|
||||
{
|
||||
|
@ -440,22 +490,24 @@ where
|
|||
/// Use [`gradient`], [`conic_gradient`] to build.
|
||||
///
|
||||
/// [`gradient`]: fn@gradient
|
||||
pub struct TiledConicGradient<S, C, A, E, T, TS> {
|
||||
pub struct TiledConicGradient<S, C, A, E, O, T, TS> {
|
||||
stops: S,
|
||||
center: C,
|
||||
angle: A,
|
||||
extend_mode: E,
|
||||
tile_origin: O,
|
||||
tile_size: T,
|
||||
tile_spacing: TS,
|
||||
data: ConicNodeData,
|
||||
tile_data: TiledNodeData,
|
||||
}
|
||||
impl<S, C, A, E, T, TS> TiledConicGradient<S, C, A, E, T, TS>
|
||||
impl<S, C, A, E, O, T, TS> TiledConicGradient<S, C, A, E, O, T, TS>
|
||||
where
|
||||
S: Var<GradientStops>,
|
||||
C: Var<Point>,
|
||||
A: Var<AngleRadian>,
|
||||
E: Var<ExtendMode>,
|
||||
O: Var<Point>,
|
||||
T: Var<Size>,
|
||||
TS: Var<Size>,
|
||||
{
|
||||
|
@ -468,7 +520,7 @@ where
|
|||
/// fully fit in the available space, so setting this to `1.lft()` will cause the *border* tiles
|
||||
/// to always touch the full bounds and the middle filled with the maximum full tiles that fit or
|
||||
/// empty space.
|
||||
pub fn tile_spacing<TS2>(self, spacing: TS2) -> TiledConicGradient<S, C, A, E, T::Var, TS2::Var>
|
||||
pub fn tile_spacing<TS2>(self, spacing: TS2) -> TiledConicGradient<S, C, A, E, O, T, TS2::Var>
|
||||
where
|
||||
TS2: IntoVar<Size>,
|
||||
{
|
||||
|
@ -477,12 +529,34 @@ where
|
|||
center: self.center,
|
||||
angle: self.angle,
|
||||
extend_mode: self.extend_mode,
|
||||
tile_origin: self.tile_origin,
|
||||
tile_size: self.tile_size,
|
||||
tile_spacing: spacing.into_var(),
|
||||
data: self.data,
|
||||
tile_data: self.tile_data,
|
||||
}
|
||||
}
|
||||
|
||||
/// Sets the tile offset.
|
||||
///
|
||||
/// Relative values are resolved on the tile size, so setting this to `100.pct()` will
|
||||
/// offset a full *turn*.
|
||||
pub fn tile_origin<O2>(self, origin: O2) -> TiledConicGradient<S, C, A, E, O2::Var, T, TS>
|
||||
where
|
||||
O2: IntoVar<Point>,
|
||||
{
|
||||
TiledConicGradient {
|
||||
stops: self.stops,
|
||||
center: self.center,
|
||||
angle: self.angle,
|
||||
extend_mode: self.extend_mode,
|
||||
tile_origin: origin.into_var(),
|
||||
tile_size: self.tile_size,
|
||||
tile_spacing: self.tile_spacing,
|
||||
data: self.data,
|
||||
tile_data: self.tile_data,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Default)]
|
||||
|
@ -533,6 +607,7 @@ where
|
|||
self.data.line,
|
||||
&self.data.stops,
|
||||
self.extend_mode.get().into(),
|
||||
PxPoint::zero(),
|
||||
self.data.size,
|
||||
PxSize::zero(),
|
||||
);
|
||||
|
@ -541,15 +616,17 @@ where
|
|||
|
||||
#[derive(Default)]
|
||||
struct TiledNodeData {
|
||||
origin: PxPoint,
|
||||
size: PxSize,
|
||||
spacing: PxSize,
|
||||
}
|
||||
#[ui_node(none)]
|
||||
impl<S, A, E, T, TS> UiNode for TiledLinearGradient<S, A, E, T, TS>
|
||||
impl<S, A, E, O, T, TS> UiNode for TiledLinearGradient<S, A, E, O, T, TS>
|
||||
where
|
||||
S: Var<GradientStops>,
|
||||
A: Var<LinearGradientAxis>,
|
||||
E: Var<ExtendMode>,
|
||||
O: Var<Point>,
|
||||
T: Var<Size>,
|
||||
TS: Var<Size>,
|
||||
{
|
||||
|
@ -558,6 +635,7 @@ where
|
|||
.sub_var_layout(&self.axis)
|
||||
.sub_var_layout(&self.stops)
|
||||
.sub_var_layout(&self.extend_mode)
|
||||
.sub_var_layout(&self.tile_origin)
|
||||
.sub_var_layout(&self.tile_size)
|
||||
.sub_var_layout(&self.tile_spacing);
|
||||
}
|
||||
|
@ -579,6 +657,7 @@ where
|
|||
self.tile_data.spacing = self.tile_spacing.layout();
|
||||
});
|
||||
self.data.line = self.axis.layout();
|
||||
self.tile_data.origin = self.tile_origin.layout();
|
||||
});
|
||||
|
||||
let length = self.data.line.length();
|
||||
|
@ -598,6 +677,7 @@ where
|
|||
self.data.line,
|
||||
&self.data.stops,
|
||||
self.extend_mode.get().into(),
|
||||
self.tile_data.origin,
|
||||
self.tile_data.size,
|
||||
self.tile_data.spacing,
|
||||
);
|
||||
|
@ -663,6 +743,7 @@ where
|
|||
self.data.radius,
|
||||
&self.data.stops,
|
||||
self.extend_mode.get().into(),
|
||||
PxPoint::zero(),
|
||||
self.data.size,
|
||||
PxSize::zero(),
|
||||
);
|
||||
|
@ -670,12 +751,13 @@ where
|
|||
}
|
||||
|
||||
#[ui_node(none)]
|
||||
impl<S, C, R, E, T, TS> UiNode for TiledRadialGradient<S, C, R, E, T, TS>
|
||||
impl<S, C, R, E, O, T, TS> UiNode for TiledRadialGradient<S, C, R, E, O, T, TS>
|
||||
where
|
||||
S: Var<GradientStops>,
|
||||
C: Var<Point>,
|
||||
R: Var<GradientRadius>,
|
||||
E: Var<ExtendMode>,
|
||||
O: Var<Point>,
|
||||
T: Var<Size>,
|
||||
TS: Var<Size>,
|
||||
{
|
||||
|
@ -685,6 +767,7 @@ where
|
|||
.sub_var_layout(&self.radius)
|
||||
.sub_var_layout(&self.stops)
|
||||
.sub_var_layout(&self.extend_mode)
|
||||
.sub_var_layout(&self.tile_origin)
|
||||
.sub_var_layout(&self.tile_size)
|
||||
.sub_var_layout(&self.tile_spacing);
|
||||
}
|
||||
|
@ -706,6 +789,7 @@ where
|
|||
});
|
||||
self.data.center = self.center.layout_dft(self.tile_data.size.to_vector().to_point() * 0.5.fct());
|
||||
self.data.radius = self.radius.get().layout(self.data.center);
|
||||
self.tile_data.origin = self.tile_origin.layout();
|
||||
});
|
||||
|
||||
LAYOUT.with_constraints(
|
||||
|
@ -730,6 +814,7 @@ where
|
|||
self.data.radius,
|
||||
&self.data.stops,
|
||||
self.extend_mode.get().into(),
|
||||
self.tile_data.origin,
|
||||
self.tile_data.size,
|
||||
self.tile_data.spacing,
|
||||
);
|
||||
|
@ -793,6 +878,7 @@ where
|
|||
self.angle.get(),
|
||||
&self.data.stops,
|
||||
self.extend_mode.get().into(),
|
||||
PxPoint::zero(),
|
||||
self.data.size,
|
||||
PxSize::zero(),
|
||||
);
|
||||
|
@ -800,12 +886,13 @@ where
|
|||
}
|
||||
|
||||
#[ui_node(none)]
|
||||
impl<S, C, A, E, T, TS> UiNode for TiledConicGradient<S, C, A, E, T, TS>
|
||||
impl<S, C, A, E, O, T, TS> UiNode for TiledConicGradient<S, C, A, E, O, T, TS>
|
||||
where
|
||||
S: Var<GradientStops>,
|
||||
C: Var<Point>,
|
||||
A: Var<AngleRadian>,
|
||||
E: Var<ExtendMode>,
|
||||
O: Var<Point>,
|
||||
T: Var<Size>,
|
||||
TS: Var<Size>,
|
||||
{
|
||||
|
@ -815,6 +902,7 @@ where
|
|||
.sub_var_layout(&self.angle)
|
||||
.sub_var_layout(&self.stops)
|
||||
.sub_var_layout(&self.extend_mode)
|
||||
.sub_var_layout(&self.tile_origin)
|
||||
.sub_var_layout(&self.tile_size)
|
||||
.sub_var_layout(&self.tile_spacing);
|
||||
}
|
||||
|
@ -835,6 +923,7 @@ where
|
|||
self.tile_data.spacing = self.tile_spacing.layout();
|
||||
});
|
||||
self.data.center = self.center.get().layout_dft(self.tile_data.size.to_vector().to_point() * 0.5.fct());
|
||||
self.tile_data.origin = self.tile_origin.layout();
|
||||
});
|
||||
|
||||
let perimeter = Px({
|
||||
|
@ -859,6 +948,7 @@ where
|
|||
self.angle.get(),
|
||||
&self.data.stops,
|
||||
self.extend_mode.get().into(),
|
||||
self.tile_data.origin,
|
||||
self.tile_data.size,
|
||||
self.tile_data.spacing,
|
||||
);
|
||||
|
|
|
@ -1237,6 +1237,7 @@ pub fn overscroll_node(child: impl UiNode) -> impl UiNode {
|
|||
radius,
|
||||
&stops,
|
||||
ExtendMode::Clamp.into(),
|
||||
PxPoint::zero(),
|
||||
v_rect.size,
|
||||
PxSize::zero(),
|
||||
);
|
||||
|
@ -1254,6 +1255,7 @@ pub fn overscroll_node(child: impl UiNode) -> impl UiNode {
|
|||
radius,
|
||||
&stops,
|
||||
ExtendMode::Clamp.into(),
|
||||
PxPoint::zero(),
|
||||
h_rect.size,
|
||||
PxSize::zero(),
|
||||
);
|
||||
|
|
|
@ -4,4 +4,4 @@
|
|||
//!
|
||||
//! See [`zero_ui_wgt_checkerboard`] for the full widget API.
|
||||
|
||||
pub use zero_ui_wgt_checkerboard::{cb_offset, cb_size, colors, node, Checkerboard};
|
||||
pub use zero_ui_wgt_checkerboard::{cb_origin, cb_size, colors, Checkerboard, Colors};
|
||||
|
|
Loading…
Reference in New Issue