mirror of
https://github.com/LGUG2Z/komorebi.git
synced 2026-03-28 20:21:57 +01:00
fix: fix horizontal-stack out of monitor with vertical flip (db28e25) feat: add resize of right-main-vertical-stack layout with filp (28dd546)
178 lines
5.9 KiB
Rust
178 lines
5.9 KiB
Rust
use clap::ValueEnum;
|
|
use schemars::JsonSchema;
|
|
use serde::Deserialize;
|
|
use serde::Serialize;
|
|
use strum::Display;
|
|
use strum::EnumString;
|
|
|
|
use crate::OperationDirection;
|
|
use crate::Rect;
|
|
use crate::Sizing;
|
|
|
|
#[derive(
|
|
Clone,
|
|
Copy,
|
|
Debug,
|
|
Serialize,
|
|
Deserialize,
|
|
Eq,
|
|
PartialEq,
|
|
Display,
|
|
EnumString,
|
|
ValueEnum,
|
|
JsonSchema,
|
|
)]
|
|
pub enum DefaultLayout {
|
|
BSP,
|
|
Columns,
|
|
Rows,
|
|
VerticalStack,
|
|
HorizontalStack,
|
|
UltrawideVerticalStack,
|
|
Grid,
|
|
RightMainVerticalStack,
|
|
// NOTE: If any new layout is added, please make sure to register the same in `DefaultLayout::cycle`
|
|
}
|
|
|
|
impl DefaultLayout {
|
|
#[must_use]
|
|
#[allow(clippy::cast_precision_loss, clippy::only_used_in_recursion)]
|
|
pub fn resize(
|
|
&self,
|
|
unaltered: &Rect,
|
|
resize: &Option<Rect>,
|
|
edge: OperationDirection,
|
|
sizing: Sizing,
|
|
delta: i32,
|
|
) -> Option<Rect> {
|
|
if !matches!(
|
|
self,
|
|
Self::BSP
|
|
| Self::Columns
|
|
| Self::Rows
|
|
| Self::VerticalStack
|
|
| Self::RightMainVerticalStack
|
|
| Self::HorizontalStack
|
|
| Self::UltrawideVerticalStack
|
|
) {
|
|
return None;
|
|
};
|
|
|
|
let max_divisor = 1.005;
|
|
let mut r = resize.unwrap_or_default();
|
|
|
|
let resize_delta = delta;
|
|
|
|
match edge {
|
|
OperationDirection::Left => match sizing {
|
|
Sizing::Increase => {
|
|
// Some final checks to make sure the user can't infinitely resize to
|
|
// the point of pushing other windows out of bounds
|
|
|
|
// Note: These checks cannot take into account the changes made to the
|
|
// edges of adjacent windows at operation time, so it is still possible
|
|
// to push windows out of bounds by maxing out an Increase Left on a
|
|
// Window with index 1, and then maxing out a Decrease Right on a Window
|
|
// with index 0. I don't think it's worth trying to defensively program
|
|
// against this; if people end up in this situation they are better off
|
|
// just hitting the retile command
|
|
let diff = ((r.left + -resize_delta) as f32).abs();
|
|
let max = unaltered.right as f32 / max_divisor;
|
|
if diff < max {
|
|
r.left += -resize_delta;
|
|
}
|
|
}
|
|
Sizing::Decrease => {
|
|
let diff = ((r.left - -resize_delta) as f32).abs();
|
|
let max = unaltered.right as f32 / max_divisor;
|
|
if diff < max {
|
|
r.left -= -resize_delta;
|
|
}
|
|
}
|
|
},
|
|
OperationDirection::Up => match sizing {
|
|
Sizing::Increase => {
|
|
let diff = ((r.top + resize_delta) as f32).abs();
|
|
let max = unaltered.bottom as f32 / max_divisor;
|
|
if diff < max {
|
|
r.top += -resize_delta;
|
|
}
|
|
}
|
|
Sizing::Decrease => {
|
|
let diff = ((r.top - resize_delta) as f32).abs();
|
|
let max = unaltered.bottom as f32 / max_divisor;
|
|
if diff < max {
|
|
r.top -= -resize_delta;
|
|
}
|
|
}
|
|
},
|
|
OperationDirection::Right => match sizing {
|
|
Sizing::Increase => {
|
|
let diff = ((r.right + resize_delta) as f32).abs();
|
|
let max = unaltered.right as f32 / max_divisor;
|
|
if diff < max {
|
|
r.right += resize_delta;
|
|
}
|
|
}
|
|
Sizing::Decrease => {
|
|
let diff = ((r.right - resize_delta) as f32).abs();
|
|
let max = unaltered.right as f32 / max_divisor;
|
|
if diff < max {
|
|
r.right -= resize_delta;
|
|
}
|
|
}
|
|
},
|
|
OperationDirection::Down => match sizing {
|
|
Sizing::Increase => {
|
|
let diff = ((r.bottom + resize_delta) as f32).abs();
|
|
let max = unaltered.bottom as f32 / max_divisor;
|
|
if diff < max {
|
|
r.bottom += resize_delta;
|
|
}
|
|
}
|
|
Sizing::Decrease => {
|
|
let diff = ((r.bottom - resize_delta) as f32).abs();
|
|
let max = unaltered.bottom as f32 / max_divisor;
|
|
if diff < max {
|
|
r.bottom -= resize_delta;
|
|
}
|
|
}
|
|
},
|
|
};
|
|
|
|
if r.eq(&Rect::default()) {
|
|
None
|
|
} else {
|
|
Option::from(r)
|
|
}
|
|
}
|
|
|
|
#[must_use]
|
|
pub const fn cycle_next(self) -> Self {
|
|
match self {
|
|
Self::BSP => Self::Columns,
|
|
Self::Columns => Self::Rows,
|
|
Self::Rows => Self::VerticalStack,
|
|
Self::VerticalStack => Self::HorizontalStack,
|
|
Self::HorizontalStack => Self::UltrawideVerticalStack,
|
|
Self::UltrawideVerticalStack => Self::Grid,
|
|
Self::Grid => Self::RightMainVerticalStack,
|
|
Self::RightMainVerticalStack => Self::BSP,
|
|
}
|
|
}
|
|
|
|
#[must_use]
|
|
pub const fn cycle_previous(self) -> Self {
|
|
match self {
|
|
Self::BSP => Self::UltrawideVerticalStack,
|
|
Self::UltrawideVerticalStack => Self::HorizontalStack,
|
|
Self::HorizontalStack => Self::VerticalStack,
|
|
Self::VerticalStack => Self::Rows,
|
|
Self::Rows => Self::Columns,
|
|
Self::Columns => Self::Grid,
|
|
Self::Grid => Self::RightMainVerticalStack,
|
|
Self::RightMainVerticalStack => Self::BSP,
|
|
}
|
|
}
|
|
}
|