#![allow(clippy::print_stdout)]
use hyprland::shared::{Address, MonitorId};
use random_color::RandomColor;
use svg::node::element::{Group, Rectangle, Text, SVG};
use crate::{ClientData, MonitorData};
mod many_windows;
mod multi_workspace_multi_monitor_horizontal;
mod multi_workspaces;
mod simple;
pub fn is_sorted(data: &[(Address, ClientData)]) -> bool {
data.windows(2).all(|l| {
l[0].0
.to_string()
.trim_start_matches("0x")
.parse::<u16>()
.unwrap()
< l[1]
.0
.to_string()
.trim_start_matches("0x")
.parse::<u16>()
.unwrap()
})
}
pub fn create_svg_from_client_tests(
clients: &[(Address, ClientData)],
filename: &str,
monitor_data: Vec<(MonitorId, MonitorData)>,
) {
let mut a = filename.split('/').collect::<Vec<&str>>();
let mut n = "";
a.remove(0);
if monitor_data.len() == 1 {
n = a.pop().expect("unable to pop filename");
}
let filename = "test-svgs/".to_owned() + &*a.join("/");
std::fs::create_dir_all(filename.clone())
.expect("unable to create test-svgs directory and subdirectories");
for (iden, monitor) in &monitor_data {
let cl: Vec<(usize, u16, u16, u16, u16, String)> = clients
.iter()
.enumerate()
.filter(|(_, (_, c))| c.monitor == *iden)
.map(|(i, (a, c))| {
(
i,
c.x * 10,
c.y * 10,
c.width * 10,
c.height * 10,
a.to_string(),
)
})
.map(|(i, x, y, w, h, iden)| (i, x as u16, y as u16, w as u16, h as u16, iden))
.collect();
let iden = if monitor_data.len() != 1 {
iden.to_string()
} else {
n.to_owned()
};
let wid = cl
.iter()
.map(|(_, x, _, w, _, _)| x + w)
.max()
.expect("no clients")
+ 10;
create_svg(
cl,
format!("{filename}/{iden}.svg"),
0,
0,
wid,
monitor.height * 10 + 10,
2,
);
}
}
pub fn create_svg(
rectangles: Vec<(usize, u16, u16, u16, u16, String)>,
filename: String,
x: u16,
y: u16,
width: u16,
height: u16,
stroke_width: u16,
) {
let mut svg = SVG::new()
.set("width", "100%")
.set("height", "100%")
.set("viewBox", format!("{} {} {} {}", x, y, width, height));
svg = svg.add(
Rectangle::new()
.set("x", x)
.set("y", y)
.set("width", width)
.set("height", height)
.set("fill", "grey"),
);
for (i, x, y, width, height, identifier) in rectangles {
let color = RandomColor::new().to_hsl_array();
let group = Group::new()
.add(
Rectangle::new()
.set("x", x)
.set("y", y)
.set("width", width)
.set("height", height)
.set(
"stroke",
format!("hsl({} {}% {}% / {}%)", color[0], color[1], color[2], 65),
)
.set("stroke-width", stroke_width)
.set("fill", "none"),
)
.add(
Text::new(format!("{i}-{identifier}"))
.set(
"x",
(x + width / 2) as i16
- ((identifier.len() as u16 * (stroke_width * 4)) / 2) as i16,
)
.set(
"y",
(y + height / 2) as i16
+ ((((stroke_width as f32 * color[0] as f32) / 90.0) as i16)
- stroke_width as i16),
)
.set("font-size", stroke_width * 4)
.set("fill", "white"),
);
svg = svg.add(group);
}
svg::save(filename.clone(), &svg).unwrap_or_else(|_| panic!("unable to save svg {filename}"));
}
#[allow(unused_macros)]
macro_rules! client_vec {
($($x:expr),+ $(,)?) => {{
use hyprland::shared::Address;
use crate::ClientData;
let mut map = Vec::new();
let mut count = 0;
$(
count += 1;
map.push((Address::new(count), ClientData {
x: $x.0,
y: $x.1,
width: $x.2,
height: $x.3,
workspace: $x.4,
monitor: $x.5,
focus_history_id: count as i8,
class: "test".to_string(),
title: "test".to_string(),
floating: false,
enabled: true,
pid: 0,
}));
)+
map
}};
}
#[allow(unused_macros)]
macro_rules! monitor_map {
($($x:expr),+ $(,)?) => {{
use hyprland::shared::MonitorId;
use crate::MonitorData;
let mut map = Vec::new();
let mut count = -1;
$(
count += 1;
map.push((count as MonitorId, MonitorData {
x: $x.0,
y: $x.1,
width: $x.2,
height: $x.3,
connector: "test".to_string(),
enabled: true,
}));
)+
map
}};
}
#[allow(unused_macros)]
macro_rules! workspace_map {
($($x:expr),+ $(,)?) => {{
use hyprland::shared::WorkspaceId;
use crate::WorkspaceData;
let mut map = Vec::new();
let mut count = -1;
$(
count += 1;
map.push((count as WorkspaceId, WorkspaceData {
x: $x.0,
y: $x.1,
width: 0,
height: 0,
name: "test".to_string(),
monitor: $x.2,
enabled: true,
}));
)+
map
}};
}
#[allow(unused_macros)]
macro_rules! function {
() => {{
fn f() {}
fn type_name_of<T>(_: T) -> &'static str {
std::any::type_name::<T>()
}
let name = type_name_of(f);
let mut filename = file!().split("/").collect::<Vec<&str>>();
if let Some(last) = filename.last() {
if *last == "mod.rs" {
filename.pop();
}
}
let filename = filename.join("/");
&(filename
+ "/"
+ match &name[..name.len() - 3].rfind(':') {
Some(pos) => &name[pos + 1..name.len() - 3],
None => &name[..name.len() - 3],
})
}};
}
#[allow(unused_imports)]
pub(crate) use client_vec;
#[allow(unused_imports)]
pub(crate) use function;
#[allow(unused_imports)]
pub(crate) use monitor_map;
#[allow(unused_imports)]
pub(crate) use workspace_map;