Skip to content

Commit ce5a466

Browse files
committed
more spacing
1 parent 3ed7095 commit ce5a466

1 file changed

Lines changed: 175 additions & 4 deletions

File tree

src/geometry.rs

Lines changed: 175 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -312,7 +312,7 @@ impl Size {
312312
}
313313

314314
#[pyclass(frozen)]
315-
#[derive(Debug, Clone)]
315+
#[derive(Debug, Clone, Copy)]
316316
pub struct Region {
317317
#[pyo3(get)]
318318
pub x: i32,
@@ -736,7 +736,6 @@ impl Region {
736736
}
737737

738738
fn intersection(&self, region: &Region) -> Region {
739-
// Unrolled because this method is used a lot
740739
let (x1, y1, w1, h1) = (self.x, self.y, self.width, self.height);
741740
let (cx1, cy1, w2, h2) = (region.x, region.y, region.width, region.height);
742741
let x2 = x1 + w1;
@@ -919,10 +918,73 @@ impl Region {
919918
height,
920919
}
921920
}
921+
922+
fn constrain(
923+
&self,
924+
constrain_x: &str,
925+
constrain_y: &str,
926+
margin: &Spacing,
927+
container: &Region,
928+
) -> Region {
929+
let margin_region = self.grow(margin._as_tuple());
930+
let mut region = *self;
931+
932+
fn compare_span(
933+
span_start: i32,
934+
span_end: i32,
935+
container_start: i32,
936+
container_end: i32,
937+
) -> i32 {
938+
if span_start > container_start && span_end <= container_end {
939+
0
940+
} else if span_start < container_start {
941+
-1
942+
} else {
943+
1
944+
}
945+
}
946+
947+
if constrain_x == "inflect" || constrain_y == "inflect" {
948+
let x_axis = if constrain_x == "inflect" {
949+
-compare_span(
950+
margin_region.x,
951+
margin_region.right(),
952+
container.x,
953+
container.right(),
954+
)
955+
} else {
956+
0
957+
};
958+
let y_axis = if constrain_y == "inflect" {
959+
-compare_span(
960+
margin_region.y,
961+
margin_region.bottom(),
962+
container.y,
963+
container.bottom(),
964+
)
965+
} else {
966+
0
967+
};
968+
region = region.inflect(x_axis, y_axis, Some(*margin))
969+
}
970+
971+
region.translate_inside(
972+
&container.shrink(margin._as_tuple()),
973+
constrain_x != "none",
974+
constrain_y != "none",
975+
)
976+
}
977+
}
978+
979+
enum SpacingDimensions {
980+
Single(i32),
981+
Tuple1(i32),
982+
Tuple2(i32, i32),
983+
Tuple4(i32, i32, i32, i32),
922984
}
923985

924986
#[pyclass(frozen)]
925-
#[derive(Debug, Clone)]
987+
#[derive(Debug, Clone, Copy)]
926988
pub struct Spacing {
927989
#[pyo3(get)]
928990
pub top: i32,
@@ -936,8 +998,8 @@ pub struct Spacing {
936998

937999
#[pymethods]
9381000
impl Spacing {
1001+
#[new]
9391002
fn new(
940-
&self,
9411003
top: Option<i32>,
9421004
right: Option<i32>,
9431005
bottom: Option<i32>,
@@ -972,6 +1034,10 @@ impl Spacing {
9721034
4
9731035
}
9741036

1037+
fn _as_tuple(&self) -> (i32, i32, i32, i32) {
1038+
(self.top, self.right, self.bottom, self.left)
1039+
}
1040+
9751041
#[getter]
9761042
fn width(&self) -> i32 {
9771043
self.left + self.right
@@ -995,4 +1061,109 @@ impl Spacing {
9951061
fn __bool__(&self) -> bool {
9961062
self.top != 0 || self.right != 0 || self.bottom != 0 || self.right != 0
9971063
}
1064+
1065+
#[getter]
1066+
fn css(&self) -> String {
1067+
let Spacing {
1068+
top,
1069+
right,
1070+
bottom,
1071+
left,
1072+
} = *self;
1073+
if top == right && right == bottom && bottom == left && left == top {
1074+
format!("{}", top)
1075+
} else if (top, right) == (bottom, left) {
1076+
format!("{} {}", top, right)
1077+
} else {
1078+
format!("{} {} {} {}", top, right, bottom, left)
1079+
}
1080+
}
1081+
1082+
#[classmethod]
1083+
fn unpack(_cls: &Bound<'_, PyType>, pad: &Bound<PyAny>) -> PyResult<Spacing> {
1084+
if let Ok(space) = pad.extract::<i32>() {
1085+
Ok(Spacing {
1086+
top: space,
1087+
right: space,
1088+
bottom: space,
1089+
left: space,
1090+
})
1091+
} else if let Ok((space,)) = pad.extract::<(i32,)>() {
1092+
Ok(Spacing {
1093+
top: space,
1094+
right: space,
1095+
bottom: space,
1096+
left: space,
1097+
})
1098+
} else if let Ok((top, right)) = pad.extract::<(i32, i32)>() {
1099+
Ok(Spacing {
1100+
top: top,
1101+
right: right,
1102+
bottom: top,
1103+
left: right,
1104+
})
1105+
} else if let Ok((top, right, bottom, left)) = pad.extract::<(i32, i32, i32, i32)>() {
1106+
Ok(Spacing {
1107+
top: top,
1108+
right: right,
1109+
bottom: bottom,
1110+
left: left,
1111+
})
1112+
} else {
1113+
Err(PyTypeError::new_err(
1114+
"Expected integer or tuple of 1, 2, 4 integers",
1115+
))
1116+
}
1117+
}
1118+
1119+
#[classmethod]
1120+
fn vertical(_cls: &Bound<'_, PyType>, amount: i32) -> Spacing {
1121+
Spacing {
1122+
top: amount,
1123+
right: 0,
1124+
bottom: amount,
1125+
left: 0,
1126+
}
1127+
}
1128+
1129+
#[classmethod]
1130+
fn horizontal(_cls: &Bound<'_, PyType>, amount: i32) -> Spacing {
1131+
Spacing {
1132+
top: 0,
1133+
right: amount,
1134+
bottom: 0,
1135+
left: amount,
1136+
}
1137+
}
1138+
1139+
#[classmethod]
1140+
fn all(_cls: &Bound<'_, PyType>, amount: i32) -> Spacing {
1141+
Spacing {
1142+
top: amount,
1143+
right: amount,
1144+
bottom: amount,
1145+
left: amount,
1146+
}
1147+
}
1148+
1149+
fn grow_maximum(&self, other: &Spacing) -> Spacing {
1150+
let Spacing {
1151+
top,
1152+
right,
1153+
bottom,
1154+
left,
1155+
} = *self;
1156+
let Spacing {
1157+
top: other_top,
1158+
right: other_right,
1159+
bottom: other_bottom,
1160+
left: other_left,
1161+
} = *other;
1162+
Spacing {
1163+
top: top.max(other_top),
1164+
right: right.max(other_right),
1165+
bottom: bottom.max(other_bottom),
1166+
left: left.max(other_left),
1167+
}
1168+
}
9981169
}

0 commit comments

Comments
 (0)