fix(wayland/xdg/positioner): properly calculate with gravity
This commit is contained in:
@@ -17,11 +17,37 @@ pub struct PositionerData {
|
|||||||
pub anchor_rect: Geometry,
|
pub anchor_rect: Geometry,
|
||||||
pub offset: Vector2<i32>,
|
pub offset: Vector2<i32>,
|
||||||
pub anchor: Anchor,
|
pub anchor: Anchor,
|
||||||
|
pub gravity: Gravity,
|
||||||
pub constraint_adjustment: ConstraintAdjustment,
|
pub constraint_adjustment: ConstraintAdjustment,
|
||||||
pub reactive: bool,
|
pub reactive: bool,
|
||||||
pub parent_size: Vector2<u32>,
|
pub parent_size: Vector2<u32>,
|
||||||
}
|
}
|
||||||
impl PositionerData {
|
impl PositionerData {
|
||||||
|
fn gravity_has_edge(&self, edge: Gravity) -> bool {
|
||||||
|
match edge {
|
||||||
|
Gravity::Top => {
|
||||||
|
self.gravity == Gravity::Top
|
||||||
|
|| self.gravity == Gravity::TopLeft
|
||||||
|
|| self.gravity == Gravity::TopRight
|
||||||
|
}
|
||||||
|
Gravity::Bottom => {
|
||||||
|
self.gravity == Gravity::Bottom
|
||||||
|
|| self.gravity == Gravity::BottomLeft
|
||||||
|
|| self.gravity == Gravity::BottomRight
|
||||||
|
}
|
||||||
|
Gravity::Left => {
|
||||||
|
self.gravity == Gravity::Left
|
||||||
|
|| self.gravity == Gravity::TopLeft
|
||||||
|
|| self.gravity == Gravity::BottomLeft
|
||||||
|
}
|
||||||
|
Gravity::Right => {
|
||||||
|
self.gravity == Gravity::Right
|
||||||
|
|| self.gravity == Gravity::TopRight
|
||||||
|
|| self.gravity == Gravity::BottomRight
|
||||||
|
}
|
||||||
|
_ => unreachable!(),
|
||||||
|
}
|
||||||
|
}
|
||||||
pub fn infinite_geometry(&self) -> Geometry {
|
pub fn infinite_geometry(&self) -> Geometry {
|
||||||
let anchor_point = match self.anchor {
|
let anchor_point = match self.anchor {
|
||||||
Anchor::TopLeft => self.anchor_rect.origin,
|
Anchor::TopLeft => self.anchor_rect.origin,
|
||||||
@@ -67,30 +93,29 @@ impl PositionerData {
|
|||||||
.into(),
|
.into(),
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut position = anchor_point;
|
let mut geometry = Geometry {
|
||||||
|
origin: [
|
||||||
// Apply gravity
|
anchor_point.x + self.offset.x,
|
||||||
if self
|
anchor_point.y + self.offset.y,
|
||||||
.constraint_adjustment
|
]
|
||||||
.contains(ConstraintAdjustment::FlipX)
|
.into(),
|
||||||
{
|
|
||||||
position.x -= self.size.x as i32;
|
|
||||||
}
|
|
||||||
if self
|
|
||||||
.constraint_adjustment
|
|
||||||
.contains(ConstraintAdjustment::FlipY)
|
|
||||||
{
|
|
||||||
position.y -= self.size.y as i32;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Apply offset
|
|
||||||
position.x += self.offset.x;
|
|
||||||
position.y += self.offset.y;
|
|
||||||
|
|
||||||
Geometry {
|
|
||||||
origin: position,
|
|
||||||
size: self.size,
|
size: self.size,
|
||||||
|
};
|
||||||
|
|
||||||
|
// apply gravity
|
||||||
|
if self.gravity_has_edge(Gravity::Top) {
|
||||||
|
geometry.origin.y -= geometry.size.y as i32;
|
||||||
|
} else if !self.gravity_has_edge(Gravity::Bottom) {
|
||||||
|
geometry.origin.y -= (geometry.size.y / 2) as i32;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if self.gravity_has_edge(Gravity::Left) {
|
||||||
|
geometry.origin.x -= geometry.size.x as i32;
|
||||||
|
} else if !self.gravity_has_edge(Gravity::Right) {
|
||||||
|
geometry.origin.x -= (geometry.size.x / 2) as i32;
|
||||||
|
}
|
||||||
|
|
||||||
|
geometry
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
impl Default for PositionerData {
|
impl Default for PositionerData {
|
||||||
@@ -100,6 +125,7 @@ impl Default for PositionerData {
|
|||||||
anchor_rect: Default::default(),
|
anchor_rect: Default::default(),
|
||||||
offset: [0, 0].into(),
|
offset: [0, 0].into(),
|
||||||
anchor: Anchor::TopLeft,
|
anchor: Anchor::TopLeft,
|
||||||
|
gravity: Gravity::TopLeft,
|
||||||
constraint_adjustment: ConstraintAdjustment::empty(),
|
constraint_adjustment: ConstraintAdjustment::empty(),
|
||||||
reactive: false,
|
reactive: false,
|
||||||
parent_size: [0; 2].into(),
|
parent_size: [0; 2].into(),
|
||||||
@@ -168,8 +194,10 @@ impl XdgPositioner for Positioner {
|
|||||||
&self,
|
&self,
|
||||||
_client: &mut Client,
|
_client: &mut Client,
|
||||||
_sender_id: ObjectId,
|
_sender_id: ObjectId,
|
||||||
_gravity: Gravity,
|
gravity: Gravity,
|
||||||
) -> Result<()> {
|
) -> Result<()> {
|
||||||
|
let mut data = self.data.lock();
|
||||||
|
data.gravity = gravity;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user