Qwen-Image-Layered-MRP-MLX/src/mflux/ui/box_values.py

81 lines
2.6 KiB
Python

from dataclasses import dataclass
@dataclass
class AbsoluteBoxValues:
top: int
right: int
bottom: int
left: int
@dataclass
class BoxValues:
top: int | str
right: int | str
bottom: int | str
left: int | str
def normalize_to_dimensions(self, width, height) -> AbsoluteBoxValues:
parts = []
dimension_base = [height, width, height, width]
for index, part in enumerate([self.top, self.right, self.bottom, self.left]):
if isinstance(part, str) and part.endswith("%"):
parts.append(int(int(part.strip("%")) / 100 * dimension_base[index]))
else:
# simple integer value
parts.append(int(part))
return AbsoluteBoxValues(*parts)
class BoxValueError(ValueError):
pass
def parse_box_value(value, delimiter=","):
"""
Parse CSS-style padding values into a dictionary.
Accepts formats:
- Single value (all sides)
- Two values (vertical | horizontal)
- Three values (top | horizontal | bottom)
- Four values (top | right | bottom | left)
Args:
value: A string containing CSS-style box values
Returns:
BoxValues dataclass with 'top', 'right', 'bottom', and 'left' attributes
"""
parts = []
for part_value in value.strip().split(delimiter):
try:
part = int(part_value.strip())
parts.append(part)
except ValueError: # noqa: PERF203
# not an int - is it a %?
if (part_value := part_value.strip()).endswith("%"):
parts.append(part_value)
else:
raise BoxValueError(f"Invalid padding value: {part_value}")
if len(parts) == 1:
# If only one value is provided, apply to all sides
return BoxValues(top=parts[0], right=parts[0], bottom=parts[0], left=parts[0])
elif len(parts) == 2:
# If two values: first is top/bottom, second is left/right
return BoxValues(top=parts[0], right=parts[1], bottom=parts[0], left=parts[1])
elif len(parts) == 3:
# If three values: top, left/right, bottom
return BoxValues(top=parts[0], right=parts[1], bottom=parts[2], left=parts[1])
elif len(parts) == 4:
# If four values: top, right, bottom, left
return BoxValues(top=parts[0], right=parts[1], bottom=parts[2], left=parts[3])
else:
raise BoxValueError(
"Invalid outpaint padding box value format: {value} "
"Expected: 1 (all-sides), 2 (top/bottom, left/right) "
"or 4 (top, right, bottom, left)values of int or percentages. e.g. 10px, 20%"
)