Upgrade to Taffy 0.3.3 (#7859)
# Objective Upgrade to Taffy 0.3.3 Fixes: #7712 ## Solution Upgrade to Taffy 0.3.3 with the `grid` feature disabled. --- ## Changelog * Changed Taffy version to 0.3.3 and disabled its `grid` feature. * Added the `Start` and `End` variants to `AlignItems`, `AlignSelf`, `AlignContent` and `JustifyContent`. * Added the `SpaceEvenly` variant to `AlignContent`. * Updated `from_style` for Taffy 0.3.3.
This commit is contained in:
parent
a213c8ac94
commit
76058bcf33
@ -31,7 +31,7 @@ bevy_window = { path = "../bevy_window", version = "0.9.0" }
|
||||
bevy_utils = { path = "../bevy_utils", version = "0.9.0" }
|
||||
|
||||
# other
|
||||
taffy = "0.2.2"
|
||||
taffy = { version = "0.3.3", default-features = false, features = ["std"] }
|
||||
serde = { version = "1", features = ["derive"] }
|
||||
smallvec = { version = "1.6", features = ["union", "const_generics"] }
|
||||
bytemuck = { version = "1.5", features = ["derive"] }
|
||||
|
@ -1,67 +1,136 @@
|
||||
use taffy::style::LengthPercentageAuto;
|
||||
|
||||
use crate::{
|
||||
AlignContent, AlignItems, AlignSelf, Display, FlexDirection, FlexWrap, JustifyContent,
|
||||
PositionType, Size, Style, UiRect, Val,
|
||||
};
|
||||
|
||||
pub fn from_rect(
|
||||
scale_factor: f64,
|
||||
rect: UiRect,
|
||||
) -> taffy::geometry::Rect<taffy::style::Dimension> {
|
||||
taffy::geometry::Rect {
|
||||
left: from_val(scale_factor, rect.left),
|
||||
right: from_val(scale_factor, rect.right),
|
||||
top: from_val(scale_factor, rect.top),
|
||||
bottom: from_val(scale_factor, rect.bottom),
|
||||
impl Val {
|
||||
fn scaled(self, scale_factor: f64) -> Self {
|
||||
match self {
|
||||
Val::Auto => Val::Auto,
|
||||
Val::Percent(value) => Val::Percent(value),
|
||||
Val::Px(value) => Val::Px((scale_factor * value as f64) as f32),
|
||||
Val::Undefined => Val::Undefined,
|
||||
}
|
||||
}
|
||||
|
||||
fn to_inset(self) -> LengthPercentageAuto {
|
||||
match self {
|
||||
Val::Auto | Val::Undefined => taffy::style::LengthPercentageAuto::Auto,
|
||||
Val::Percent(value) => taffy::style::LengthPercentageAuto::Percent(value / 100.0),
|
||||
Val::Px(value) => taffy::style::LengthPercentageAuto::Points(value),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn from_val_size(
|
||||
scale_factor: f64,
|
||||
size: Size,
|
||||
) -> taffy::geometry::Size<taffy::style::Dimension> {
|
||||
taffy::geometry::Size {
|
||||
width: from_val(scale_factor, size.width),
|
||||
height: from_val(scale_factor, size.height),
|
||||
impl UiRect {
|
||||
fn scaled(self, scale_factor: f64) -> Self {
|
||||
Self {
|
||||
left: self.left.scaled(scale_factor),
|
||||
right: self.right.scaled(scale_factor),
|
||||
top: self.top.scaled(scale_factor),
|
||||
bottom: self.bottom.scaled(scale_factor),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn from_style(scale_factor: f64, value: &Style) -> taffy::style::Style {
|
||||
impl Size {
|
||||
fn scaled(self, scale_factor: f64) -> Self {
|
||||
Self {
|
||||
width: self.width.scaled(scale_factor),
|
||||
height: self.height.scaled(scale_factor),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: From<Val>> From<UiRect> for taffy::prelude::Rect<T> {
|
||||
fn from(value: UiRect) -> Self {
|
||||
Self {
|
||||
left: value.left.into(),
|
||||
right: value.right.into(),
|
||||
top: value.top.into(),
|
||||
bottom: value.bottom.into(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: From<Val>> From<Size> for taffy::prelude::Size<T> {
|
||||
fn from(value: Size) -> Self {
|
||||
Self {
|
||||
width: value.width.into(),
|
||||
height: value.height.into(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<Val> for taffy::style::Dimension {
|
||||
fn from(value: Val) -> Self {
|
||||
match value {
|
||||
Val::Auto | Val::Undefined => taffy::style::Dimension::Auto,
|
||||
Val::Percent(value) => taffy::style::Dimension::Percent(value / 100.0),
|
||||
Val::Px(value) => taffy::style::Dimension::Points(value),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<Val> for taffy::style::LengthPercentage {
|
||||
fn from(value: Val) -> Self {
|
||||
match value {
|
||||
Val::Auto | Val::Undefined => taffy::style::LengthPercentage::Points(0.0),
|
||||
Val::Percent(value) => taffy::style::LengthPercentage::Percent(value / 100.0),
|
||||
Val::Px(value) => taffy::style::LengthPercentage::Points(value),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<Val> for taffy::style::LengthPercentageAuto {
|
||||
fn from(value: Val) -> Self {
|
||||
match value {
|
||||
Val::Auto => taffy::style::LengthPercentageAuto::Auto,
|
||||
Val::Percent(value) => taffy::style::LengthPercentageAuto::Percent(value / 100.0),
|
||||
Val::Px(value) => taffy::style::LengthPercentageAuto::Points(value),
|
||||
Val::Undefined => taffy::style::LengthPercentageAuto::Points(0.),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn from_style(scale_factor: f64, style: &Style) -> taffy::style::Style {
|
||||
taffy::style::Style {
|
||||
display: value.display.into(),
|
||||
position_type: value.position_type.into(),
|
||||
flex_direction: value.flex_direction.into(),
|
||||
flex_wrap: value.flex_wrap.into(),
|
||||
align_items: value.align_items.into(),
|
||||
align_self: value.align_self.into(),
|
||||
align_content: value.align_content.into(),
|
||||
justify_content: value.justify_content.into(),
|
||||
position: from_rect(scale_factor, value.position),
|
||||
margin: from_rect(scale_factor, value.margin),
|
||||
padding: from_rect(scale_factor, value.padding),
|
||||
border: from_rect(scale_factor, value.border),
|
||||
flex_grow: value.flex_grow,
|
||||
flex_shrink: value.flex_shrink,
|
||||
flex_basis: from_val(scale_factor, value.flex_basis),
|
||||
size: from_val_size(scale_factor, value.size),
|
||||
min_size: from_val_size(scale_factor, value.min_size),
|
||||
max_size: from_val_size(scale_factor, value.max_size),
|
||||
aspect_ratio: value.aspect_ratio,
|
||||
gap: from_val_size(scale_factor, value.gap),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn from_val(scale_factor: f64, val: Val) -> taffy::style::Dimension {
|
||||
match val {
|
||||
Val::Auto => taffy::style::Dimension::Auto,
|
||||
Val::Percent(value) => taffy::style::Dimension::Percent(value / 100.0),
|
||||
Val::Px(value) => taffy::style::Dimension::Points((scale_factor * value as f64) as f32),
|
||||
Val::Undefined => taffy::style::Dimension::Undefined,
|
||||
display: style.display.into(),
|
||||
position: style.position_type.into(),
|
||||
flex_direction: style.flex_direction.into(),
|
||||
flex_wrap: style.flex_wrap.into(),
|
||||
align_items: Some(style.align_items.into()),
|
||||
align_self: style.align_self.into(),
|
||||
align_content: Some(style.align_content.into()),
|
||||
justify_content: Some(style.justify_content.into()),
|
||||
inset: taffy::prelude::Rect {
|
||||
left: style.position.left.scaled(scale_factor).to_inset(),
|
||||
right: style.position.right.scaled(scale_factor).to_inset(),
|
||||
top: style.position.top.scaled(scale_factor).to_inset(),
|
||||
bottom: style.position.bottom.scaled(scale_factor).to_inset(),
|
||||
},
|
||||
margin: style.margin.scaled(scale_factor).into(),
|
||||
padding: style.padding.scaled(scale_factor).into(),
|
||||
border: style.border.scaled(scale_factor).into(),
|
||||
flex_grow: style.flex_grow,
|
||||
flex_shrink: style.flex_shrink,
|
||||
flex_basis: style.flex_basis.scaled(scale_factor).into(),
|
||||
size: style.size.scaled(scale_factor).into(),
|
||||
min_size: style.size.scaled(scale_factor).into(),
|
||||
max_size: style.size.scaled(scale_factor).into(),
|
||||
aspect_ratio: style.aspect_ratio,
|
||||
gap: style.gap.scaled(scale_factor).into(),
|
||||
justify_self: None,
|
||||
}
|
||||
}
|
||||
|
||||
impl From<AlignItems> for taffy::style::AlignItems {
|
||||
fn from(value: AlignItems) -> Self {
|
||||
match value {
|
||||
AlignItems::Start => taffy::style::AlignItems::Start,
|
||||
AlignItems::End => taffy::style::AlignItems::End,
|
||||
AlignItems::FlexStart => taffy::style::AlignItems::FlexStart,
|
||||
AlignItems::FlexEnd => taffy::style::AlignItems::FlexEnd,
|
||||
AlignItems::Center => taffy::style::AlignItems::Center,
|
||||
@ -71,15 +140,17 @@ impl From<AlignItems> for taffy::style::AlignItems {
|
||||
}
|
||||
}
|
||||
|
||||
impl From<AlignSelf> for taffy::style::AlignSelf {
|
||||
impl From<AlignSelf> for Option<taffy::style::AlignSelf> {
|
||||
fn from(value: AlignSelf) -> Self {
|
||||
match value {
|
||||
AlignSelf::Auto => taffy::style::AlignSelf::Auto,
|
||||
AlignSelf::FlexStart => taffy::style::AlignSelf::FlexStart,
|
||||
AlignSelf::FlexEnd => taffy::style::AlignSelf::FlexEnd,
|
||||
AlignSelf::Center => taffy::style::AlignSelf::Center,
|
||||
AlignSelf::Baseline => taffy::style::AlignSelf::Baseline,
|
||||
AlignSelf::Stretch => taffy::style::AlignSelf::Stretch,
|
||||
AlignSelf::Auto => None,
|
||||
AlignSelf::Start => taffy::style::AlignSelf::Start.into(),
|
||||
AlignSelf::End => taffy::style::AlignSelf::End.into(),
|
||||
AlignSelf::FlexStart => taffy::style::AlignSelf::FlexStart.into(),
|
||||
AlignSelf::FlexEnd => taffy::style::AlignSelf::FlexEnd.into(),
|
||||
AlignSelf::Center => taffy::style::AlignSelf::Center.into(),
|
||||
AlignSelf::Baseline => taffy::style::AlignSelf::Baseline.into(),
|
||||
AlignSelf::Stretch => taffy::style::AlignSelf::Stretch.into(),
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -87,12 +158,15 @@ impl From<AlignSelf> for taffy::style::AlignSelf {
|
||||
impl From<AlignContent> for taffy::style::AlignContent {
|
||||
fn from(value: AlignContent) -> Self {
|
||||
match value {
|
||||
AlignContent::Start => taffy::style::AlignContent::Start,
|
||||
AlignContent::End => taffy::style::AlignContent::End,
|
||||
AlignContent::FlexStart => taffy::style::AlignContent::FlexStart,
|
||||
AlignContent::FlexEnd => taffy::style::AlignContent::FlexEnd,
|
||||
AlignContent::Center => taffy::style::AlignContent::Center,
|
||||
AlignContent::Stretch => taffy::style::AlignContent::Stretch,
|
||||
AlignContent::SpaceBetween => taffy::style::AlignContent::SpaceBetween,
|
||||
AlignContent::SpaceAround => taffy::style::AlignContent::SpaceAround,
|
||||
AlignContent::SpaceEvenly => taffy::style::AlignContent::SpaceEvenly,
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -120,6 +194,8 @@ impl From<FlexDirection> for taffy::style::FlexDirection {
|
||||
impl From<JustifyContent> for taffy::style::JustifyContent {
|
||||
fn from(value: JustifyContent) -> Self {
|
||||
match value {
|
||||
JustifyContent::Start => taffy::style::JustifyContent::Start,
|
||||
JustifyContent::End => taffy::style::JustifyContent::End,
|
||||
JustifyContent::FlexStart => taffy::style::JustifyContent::FlexStart,
|
||||
JustifyContent::FlexEnd => taffy::style::JustifyContent::FlexEnd,
|
||||
JustifyContent::Center => taffy::style::JustifyContent::Center,
|
||||
@ -130,11 +206,11 @@ impl From<JustifyContent> for taffy::style::JustifyContent {
|
||||
}
|
||||
}
|
||||
|
||||
impl From<PositionType> for taffy::style::PositionType {
|
||||
impl From<PositionType> for taffy::style::Position {
|
||||
fn from(value: PositionType) -> Self {
|
||||
match value {
|
||||
PositionType::Relative => taffy::style::PositionType::Relative,
|
||||
PositionType::Absolute => taffy::style::PositionType::Absolute,
|
||||
PositionType::Relative => taffy::style::Position::Relative,
|
||||
PositionType::Absolute => taffy::style::Position::Absolute,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -18,6 +18,7 @@ use bevy_window::{PrimaryWindow, Window, WindowResolution, WindowScaleFactorChan
|
||||
use std::fmt;
|
||||
use taffy::{
|
||||
prelude::{AvailableSpace, Size},
|
||||
style_helpers::TaffyMaxContent,
|
||||
Taffy,
|
||||
};
|
||||
|
||||
@ -61,14 +62,17 @@ impl FlexSurface {
|
||||
pub fn upsert_node(&mut self, entity: Entity, style: &Style, scale_factor: f64) {
|
||||
let mut added = false;
|
||||
let taffy = &mut self.taffy;
|
||||
let taffy_style = convert::from_style(scale_factor, style);
|
||||
let taffy_node = self.entity_to_taffy.entry(entity).or_insert_with(|| {
|
||||
added = true;
|
||||
taffy.new_leaf(taffy_style).unwrap()
|
||||
taffy
|
||||
.new_leaf(convert::from_style(scale_factor, style))
|
||||
.unwrap()
|
||||
});
|
||||
|
||||
if !added {
|
||||
self.taffy.set_style(*taffy_node, taffy_style).unwrap();
|
||||
self.taffy
|
||||
.set_style(*taffy_node, convert::from_style(scale_factor, style))
|
||||
.unwrap();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -353,15 +353,21 @@ impl Default for Style {
|
||||
#[derive(Copy, Clone, PartialEq, Eq, Debug, Serialize, Deserialize, Reflect)]
|
||||
#[reflect(PartialEq, Serialize, Deserialize)]
|
||||
pub enum AlignItems {
|
||||
/// Items are aligned at the start
|
||||
/// Items are packed towards the start of the axis.
|
||||
Start,
|
||||
/// Items are packed towards the end of the axis.
|
||||
End,
|
||||
/// Items are packed towards the start of the axis, unless the flex direction is reversed;
|
||||
/// then they are packed towards the end of the axis.
|
||||
FlexStart,
|
||||
/// Items are aligned at the end
|
||||
/// Items are packed towards the end of the axis, unless the flex direction is reversed;
|
||||
/// then they are packed towards the end of the axis.
|
||||
FlexEnd,
|
||||
/// Items are aligned at the center
|
||||
/// Items are aligned at the center.
|
||||
Center,
|
||||
/// Items are aligned at the baseline
|
||||
/// Items are aligned at the baseline.
|
||||
Baseline,
|
||||
/// Items are stretched across the whole cross axis
|
||||
/// Items are stretched across the whole cross axis.
|
||||
Stretch,
|
||||
}
|
||||
|
||||
@ -380,17 +386,23 @@ impl Default for AlignItems {
|
||||
#[derive(Copy, Clone, PartialEq, Eq, Debug, Serialize, Deserialize, Reflect)]
|
||||
#[reflect(PartialEq, Serialize, Deserialize)]
|
||||
pub enum AlignSelf {
|
||||
/// Use the parent node's [`AlignItems`] value to determine how this item should be aligned
|
||||
/// Use the parent node's [`AlignItems`] value to determine how this item should be aligned.
|
||||
Auto,
|
||||
/// This item will be aligned at the start
|
||||
/// This item will be aligned with the start of the axis.
|
||||
Start,
|
||||
/// This item will be aligned with the end of the axis.
|
||||
End,
|
||||
/// This item will be aligned with the start of the axis, unless the flex direction is reversed;
|
||||
/// then it will be aligned with the end of the axis.
|
||||
FlexStart,
|
||||
/// This item will be aligned at the end
|
||||
/// This item will be aligned with the start of the axis, unless the flex direction is reversed;
|
||||
/// then it will be aligned with the end of the axis.
|
||||
FlexEnd,
|
||||
/// This item will be aligned at the center
|
||||
/// This item will be aligned at the center.
|
||||
Center,
|
||||
/// This item will be aligned at the baseline
|
||||
/// This item will be aligned at the baseline.
|
||||
Baseline,
|
||||
/// This item will be stretched across the whole cross axis
|
||||
/// This item will be stretched across the whole cross axis.
|
||||
Stretch,
|
||||
}
|
||||
|
||||
@ -410,19 +422,26 @@ impl Default for AlignSelf {
|
||||
#[derive(Copy, Clone, PartialEq, Eq, Debug, Serialize, Deserialize, Reflect)]
|
||||
#[reflect(PartialEq, Serialize, Deserialize)]
|
||||
pub enum AlignContent {
|
||||
/// Each line moves towards the start of the cross axis
|
||||
/// Each line moves towards the start of the cross axis.
|
||||
Start,
|
||||
/// Each line moves towards the end of the cross axis.
|
||||
End,
|
||||
/// Each line moves towards the start of the cross axis, unless the flex direction is reversed; then the line moves towards the end of the cross axis.
|
||||
FlexStart,
|
||||
/// Each line moves towards the end of the cross axis
|
||||
/// Each line moves towards the end of the cross axis, unless the flex direction is reversed; then the line moves towards the start of the cross axis.
|
||||
FlexEnd,
|
||||
/// Each line moves towards the center of the cross axis
|
||||
/// Each line moves towards the center of the cross axis.
|
||||
Center,
|
||||
/// Each line will stretch to fill the remaining space
|
||||
/// Each line will stretch to fill the remaining space.
|
||||
Stretch,
|
||||
/// Each line fills the space it needs, putting the remaining space, if any
|
||||
/// inbetween the lines
|
||||
/// inbetween the lines.
|
||||
SpaceBetween,
|
||||
/// The gap between the first and last items is exactly THE SAME as the gap between items.
|
||||
/// The gaps are distributed evenly.
|
||||
SpaceEvenly,
|
||||
/// Each line fills the space it needs, putting the remaining space, if any
|
||||
/// around the lines
|
||||
/// around the lines.
|
||||
SpaceAround,
|
||||
}
|
||||
|
||||
@ -442,11 +461,11 @@ impl Default for AlignContent {
|
||||
#[derive(Copy, Clone, PartialEq, Eq, Debug, Serialize, Deserialize, Reflect)]
|
||||
#[reflect(PartialEq, Serialize, Deserialize)]
|
||||
pub enum Direction {
|
||||
/// Inherit from parent node
|
||||
/// Inherit from parent node.
|
||||
Inherit,
|
||||
/// Text is written left to right
|
||||
/// Text is written left to right.
|
||||
LeftToRight,
|
||||
/// Text is written right to left
|
||||
/// Text is written right to left.
|
||||
RightToLeft,
|
||||
}
|
||||
|
||||
@ -489,13 +508,13 @@ impl Default for Display {
|
||||
#[derive(Copy, Clone, PartialEq, Eq, Debug, Serialize, Deserialize, Reflect)]
|
||||
#[reflect(PartialEq, Serialize, Deserialize)]
|
||||
pub enum FlexDirection {
|
||||
/// Same way as text direction along the main axis
|
||||
/// Same way as text direction along the main axis.
|
||||
Row,
|
||||
/// Flex from top to bottom
|
||||
/// Flex from top to bottom.
|
||||
Column,
|
||||
/// Opposite way as text direction along the main axis
|
||||
/// Opposite way as text direction along the main axis.
|
||||
RowReverse,
|
||||
/// Flex from bottom to top
|
||||
/// Flex from bottom to top.
|
||||
ColumnReverse,
|
||||
}
|
||||
|
||||
@ -513,17 +532,21 @@ impl Default for FlexDirection {
|
||||
#[derive(Copy, Clone, PartialEq, Eq, Debug, Serialize, Deserialize, Reflect)]
|
||||
#[reflect(PartialEq, Serialize, Deserialize)]
|
||||
pub enum JustifyContent {
|
||||
/// Pushed towards the start
|
||||
/// Items are packed toward the start of the axis.
|
||||
Start,
|
||||
/// Items are packed toward the end of the axis.
|
||||
End,
|
||||
/// Pushed towards the start, unless the flex direction is reversed; then pushed towards the end.
|
||||
FlexStart,
|
||||
/// Pushed towards the end
|
||||
/// Pushed towards the end, unless the flex direction is reversed; then pushed towards the start.
|
||||
FlexEnd,
|
||||
/// Centered along the main axis
|
||||
/// Centered along the main axis.
|
||||
Center,
|
||||
/// Remaining space is distributed between the items
|
||||
/// Remaining space is distributed between the items.
|
||||
SpaceBetween,
|
||||
/// Remaining space is distributed around the items
|
||||
/// Remaining space is distributed around the items.
|
||||
SpaceAround,
|
||||
/// Like [`JustifyContent::SpaceAround`] but with even spacing between items
|
||||
/// Like [`JustifyContent::SpaceAround`] but with even spacing between items.
|
||||
SpaceEvenly,
|
||||
}
|
||||
|
||||
@ -541,9 +564,9 @@ impl Default for JustifyContent {
|
||||
#[derive(Copy, Clone, PartialEq, Eq, Debug, Reflect, Serialize, Deserialize)]
|
||||
#[reflect(PartialEq, Serialize, Deserialize)]
|
||||
pub enum Overflow {
|
||||
/// Show overflowing items
|
||||
/// Show overflowing items.
|
||||
Visible,
|
||||
/// Hide overflowing items
|
||||
/// Hide overflowing items.
|
||||
Hidden,
|
||||
}
|
||||
|
||||
@ -561,11 +584,11 @@ impl Default for Overflow {
|
||||
#[derive(Copy, Clone, PartialEq, Eq, Debug, Serialize, Deserialize, Reflect)]
|
||||
#[reflect(PartialEq, Serialize, Deserialize)]
|
||||
pub enum PositionType {
|
||||
/// Relative to all other nodes with the [`PositionType::Relative`] value
|
||||
/// Relative to all other nodes with the [`PositionType::Relative`] value.
|
||||
Relative,
|
||||
/// Independent of all other nodes
|
||||
/// Independent of all other nodes.
|
||||
///
|
||||
/// As usual, the `Style.position` field of this node is specified relative to its parent node
|
||||
/// As usual, the `Style.position` field of this node is specified relative to its parent node.
|
||||
Absolute,
|
||||
}
|
||||
|
||||
@ -583,11 +606,11 @@ impl Default for PositionType {
|
||||
#[derive(Copy, Clone, PartialEq, Eq, Debug, Serialize, Deserialize, Reflect)]
|
||||
#[reflect(PartialEq, Serialize, Deserialize)]
|
||||
pub enum FlexWrap {
|
||||
/// Single line, will overflow if needed
|
||||
/// Single line, will overflow if needed.
|
||||
NoWrap,
|
||||
/// Multiple lines, if needed
|
||||
/// Multiple lines, if needed.
|
||||
Wrap,
|
||||
/// Same as [`FlexWrap::Wrap`] but new lines will appear before the previous one
|
||||
/// Same as [`FlexWrap::Wrap`] but new lines will appear before the previous one.
|
||||
WrapReverse,
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user