use bitflags::bitflags;
bitflags! {
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub struct DirtyFlags: u16 {
const NONE = 0;
const LAYOUT = 1 << 0;
const TEXT_SHAPING = 1 << 1;
const CHILDREN_ORDER = 1 << 2;
const COLOR = 1 << 3;
const OPACITY = 1 << 4;
const GEOMETRY = 1 << 5;
const IMAGE = 1 << 6;
const FOCUS = 1 << 7;
const TRANSFORM = 1 << 8;
const CLIP = 1 << 9;
const VISIBILITY = 1 << 10;
const SCROLL = 1 << 11;
const Z_INDEX = 1 << 12;
}
}
impl DirtyFlags {
pub const LAYOUT_GROUP: Self = Self::LAYOUT
.union(Self::TEXT_SHAPING)
.union(Self::CHILDREN_ORDER);
pub const PAINT_GROUP: Self = Self::COLOR
.union(Self::OPACITY)
.union(Self::GEOMETRY)
.union(Self::IMAGE)
.union(Self::FOCUS);
pub const PROPAGATE_GROUP: Self = Self::LAYOUT
.union(Self::TEXT_SHAPING)
.union(Self::CHILDREN_ORDER);
#[inline]
pub fn needs_layout(&self) -> bool {
self.intersects(Self::LAYOUT_GROUP)
}
#[inline]
pub fn needs_text_shaping(&self) -> bool {
self.contains(Self::TEXT_SHAPING)
}
#[inline]
pub fn is_paint_only(&self) -> bool {
!self.is_empty()
&& !self.intersects(
Self::LAYOUT | Self::TEXT_SHAPING | Self::CHILDREN_ORDER | Self::TRANSFORM,
)
}
#[inline]
pub fn needs_geometry_rebuild(&self) -> bool {
self.intersects(
Self::LAYOUT
| Self::GEOMETRY
| Self::TEXT_SHAPING
| Self::CHILDREN_ORDER
| Self::TRANSFORM
| Self::VISIBILITY
| Self::Z_INDEX,
)
}
#[inline]
pub fn needs_clip_update(&self) -> bool {
self.intersects(Self::CLIP | Self::LAYOUT | Self::CHILDREN_ORDER | Self::TRANSFORM)
}
#[inline]
pub fn should_propagate_to_parent(&self) -> bool {
self.intersects(Self::PROPAGATE_GROUP)
}
#[inline]
pub fn propagation_flags(&self) -> Self {
*self & (Self::LAYOUT | Self::CHILDREN_ORDER)
}
}
impl Default for DirtyFlags {
fn default() -> Self {
Self::NONE
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_layout_flags() {
assert!(DirtyFlags::LAYOUT.needs_layout());
assert!(DirtyFlags::TEXT_SHAPING.needs_layout());
assert!(DirtyFlags::CHILDREN_ORDER.needs_layout());
assert!(!DirtyFlags::COLOR.needs_layout());
assert!(!DirtyFlags::OPACITY.needs_layout());
}
#[test]
fn test_paint_only() {
assert!(DirtyFlags::COLOR.is_paint_only());
assert!(DirtyFlags::OPACITY.is_paint_only());
assert!((DirtyFlags::COLOR | DirtyFlags::OPACITY).is_paint_only());
assert!(DirtyFlags::GEOMETRY.is_paint_only());
assert!(DirtyFlags::IMAGE.is_paint_only());
assert!(DirtyFlags::FOCUS.is_paint_only());
assert!(!DirtyFlags::LAYOUT.is_paint_only());
assert!(!DirtyFlags::TEXT_SHAPING.is_paint_only());
}
#[test]
fn test_propagation() {
assert!(DirtyFlags::LAYOUT.should_propagate_to_parent());
assert!(DirtyFlags::TEXT_SHAPING.should_propagate_to_parent());
assert!(DirtyFlags::CHILDREN_ORDER.should_propagate_to_parent());
assert!(!DirtyFlags::COLOR.should_propagate_to_parent());
assert!(!DirtyFlags::OPACITY.should_propagate_to_parent());
assert!(!DirtyFlags::GEOMETRY.should_propagate_to_parent());
}
#[test]
fn test_propagation_flags() {
let flags = DirtyFlags::LAYOUT | DirtyFlags::COLOR;
let propagated = flags.propagation_flags();
assert_eq!(propagated, DirtyFlags::LAYOUT);
assert!(!propagated.contains(DirtyFlags::COLOR));
}
#[test]
fn test_text_shaping() {
assert!(DirtyFlags::TEXT_SHAPING.needs_text_shaping());
assert!(!DirtyFlags::COLOR.needs_text_shaping());
assert!(!DirtyFlags::LAYOUT.needs_text_shaping());
}
#[test]
fn test_geometry_rebuild() {
assert!(DirtyFlags::LAYOUT.needs_geometry_rebuild());
assert!(DirtyFlags::GEOMETRY.needs_geometry_rebuild());
assert!(DirtyFlags::TEXT_SHAPING.needs_geometry_rebuild());
assert!(DirtyFlags::TRANSFORM.needs_geometry_rebuild());
assert!(DirtyFlags::VISIBILITY.needs_geometry_rebuild());
assert!(DirtyFlags::Z_INDEX.needs_geometry_rebuild());
assert!(!DirtyFlags::COLOR.needs_geometry_rebuild());
assert!(!DirtyFlags::OPACITY.needs_geometry_rebuild());
}
#[test]
fn test_clip_update() {
assert!(DirtyFlags::CLIP.needs_clip_update());
assert!(DirtyFlags::LAYOUT.needs_clip_update());
assert!(DirtyFlags::CHILDREN_ORDER.needs_clip_update());
assert!(DirtyFlags::TRANSFORM.needs_clip_update());
assert!(!DirtyFlags::COLOR.needs_clip_update());
assert!(!DirtyFlags::OPACITY.needs_clip_update());
assert!(!DirtyFlags::GEOMETRY.needs_clip_update());
}
#[test]
fn test_new_flags() {
assert!(DirtyFlags::IMAGE.is_paint_only());
assert!(DirtyFlags::FOCUS.is_paint_only());
assert!(DirtyFlags::VISIBILITY.is_paint_only());
assert!(DirtyFlags::SCROLL.is_paint_only());
assert!(!DirtyFlags::IMAGE.needs_layout());
assert!(!DirtyFlags::FOCUS.needs_layout());
assert!(!DirtyFlags::VISIBILITY.needs_layout());
assert!(!DirtyFlags::SCROLL.needs_layout());
}
}