| 1 |
pub mod grid;
|
| 2 |
pub mod monocle;
|
| 3 |
pub mod normie;
|
| 4 |
pub mod scrolling;
|
| 5 |
pub mod tabbed;
|
| 6 |
pub mod tiling;
|
| 7 |
|
| 8 |
use std::str::FromStr;
|
| 9 |
|
| 10 |
use x11rb::protocol::xproto::Window;
|
| 11 |
|
| 12 |
pub type LayoutBox = Box<dyn Layout>;
|
| 13 |
|
| 14 |
pub struct GapConfig {
|
| 15 |
pub inner_horizontal: u32,
|
| 16 |
pub inner_vertical: u32,
|
| 17 |
pub outer_horizontal: u32,
|
| 18 |
pub outer_vertical: u32,
|
| 19 |
}
|
| 20 |
|
| 21 |
pub enum LayoutType {
|
| 22 |
Tiling,
|
| 23 |
Normie,
|
| 24 |
Grid,
|
| 25 |
Monocle,
|
| 26 |
Tabbed,
|
| 27 |
Scrolling,
|
| 28 |
}
|
| 29 |
|
| 30 |
impl LayoutType {
|
| 31 |
pub fn to_boxed_layout(&self) -> LayoutBox {
|
| 32 |
match self {
|
| 33 |
Self::Tiling => Box::new(tiling::TilingLayout),
|
| 34 |
Self::Normie => Box::new(normie::NormieLayout),
|
| 35 |
Self::Grid => Box::new(grid::GridLayout),
|
| 36 |
Self::Monocle => Box::new(monocle::MonocleLayout),
|
| 37 |
Self::Tabbed => Box::new(tabbed::TabbedLayout),
|
| 38 |
Self::Scrolling => Box::new(scrolling::ScrollingLayout),
|
| 39 |
}
|
| 40 |
}
|
| 41 |
|
| 42 |
pub fn next(&self) -> Self {
|
| 43 |
match self {
|
| 44 |
Self::Tiling => Self::Normie,
|
| 45 |
Self::Normie => Self::Grid,
|
| 46 |
Self::Grid => Self::Monocle,
|
| 47 |
Self::Monocle => Self::Tabbed,
|
| 48 |
Self::Tabbed => Self::Scrolling,
|
| 49 |
Self::Scrolling => Self::Tiling,
|
| 50 |
}
|
| 51 |
}
|
| 52 |
|
| 53 |
pub fn as_str(&self) -> &'static str {
|
| 54 |
match self {
|
| 55 |
Self::Tiling => "tiling",
|
| 56 |
Self::Normie => "normie",
|
| 57 |
Self::Grid => "grid",
|
| 58 |
Self::Monocle => "monocle",
|
| 59 |
Self::Tabbed => "tabbed",
|
| 60 |
Self::Scrolling => "scrolling",
|
| 61 |
}
|
| 62 |
}
|
| 63 |
}
|
| 64 |
|
| 65 |
impl FromStr for LayoutType {
|
| 66 |
type Err = String;
|
| 67 |
|
| 68 |
fn from_str(s: &str) -> Result<Self, String> {
|
| 69 |
match s.to_lowercase().as_str() {
|
| 70 |
"tiling" => Ok(Self::Tiling),
|
| 71 |
"normie" | "floating" => Ok(Self::Normie),
|
| 72 |
"grid" => Ok(Self::Grid),
|
| 73 |
"monocle" => Ok(Self::Monocle),
|
| 74 |
"tabbed" => Ok(Self::Tabbed),
|
| 75 |
"scrolling" => Ok(Self::Scrolling),
|
| 76 |
_ => Err(format!("Invalid Layout Type: {}", s)),
|
| 77 |
}
|
| 78 |
}
|
| 79 |
}
|
| 80 |
|
| 81 |
pub fn layout_from_str(s: &str) -> Result<LayoutBox, String> {
|
| 82 |
let layout_type = LayoutType::from_str(s)?;
|
| 83 |
Ok(layout_type.to_boxed_layout())
|
| 84 |
}
|
| 85 |
|
| 86 |
pub fn next_layout(current_name: &str) -> &'static str {
|
| 87 |
LayoutType::from_str(current_name)
|
| 88 |
.ok()
|
| 89 |
.map(|layout_type| layout_type.next())
|
| 90 |
.unwrap_or(LayoutType::Tiling)
|
| 91 |
.as_str()
|
| 92 |
}
|
| 93 |
|
| 94 |
pub trait Layout {
|
| 95 |
fn arrange(
|
| 96 |
&self,
|
| 97 |
windows: &[Window],
|
| 98 |
screen_width: u32,
|
| 99 |
screen_height: u32,
|
| 100 |
gaps: &GapConfig,
|
| 101 |
master_factor: f32,
|
| 102 |
num_master: i32,
|
| 103 |
smartgaps_enabled: bool,
|
| 104 |
) -> Vec<WindowGeometry>;
|
| 105 |
fn name(&self) -> &'static str;
|
| 106 |
fn symbol(&self) -> &'static str;
|
| 107 |
}
|
| 108 |
|
| 109 |
#[derive(Clone)]
|
| 110 |
pub struct WindowGeometry {
|
| 111 |
pub x_coordinate: i32,
|
| 112 |
pub y_coordinate: i32,
|
| 113 |
pub width: u32,
|
| 114 |
pub height: u32,
|
| 115 |
}
|