use crate::error::Result;
use crate::surface::Surface;
use std::sync::{Mutex, OnceLock};
static PANEL_STACK: OnceLock<Mutex<Vec<usize>>> = OnceLock::new();
pub struct Layer {
surface: Surface,
layer_id: usize,
hidden: bool,
}
impl Layer {
pub fn new(surface: Surface) -> Result<Self> {
let layer_id = Self::register_layer();
Ok(Self {
surface,
layer_id,
hidden: false,
})
}
pub fn surface(&self) -> &Surface {
&self.surface
}
pub fn surface_mut(&mut self) -> &mut Surface {
&mut self.surface
}
pub fn top(&mut self) -> Result<()> {
let stack = PANEL_STACK.get_or_init(|| Mutex::new(Vec::new()));
let mut guard = stack.lock().unwrap();
if let Some(pos) = guard.iter().position(|&id| id == self.layer_id) {
guard.remove(pos);
guard.push(self.layer_id);
}
Ok(())
}
pub fn bottom(&mut self) -> Result<()> {
let stack = PANEL_STACK.get_or_init(|| Mutex::new(Vec::new()));
let mut guard = stack.lock().unwrap();
if let Some(pos) = guard.iter().position(|&id| id == self.layer_id) {
guard.remove(pos);
guard.insert(0, self.layer_id);
}
Ok(())
}
pub fn hide(&mut self) -> Result<()> {
self.hidden = true;
Ok(())
}
pub fn show(&mut self) -> Result<()> {
self.hidden = false;
Ok(())
}
pub fn is_hidden(&self) -> bool {
self.hidden
}
pub fn refresh(&mut self) -> Result<()> {
if !self.hidden {
self.surface.refresh()
} else {
Ok(())
}
}
pub fn wnoutrefresh(&mut self) -> Result<()> {
if !self.hidden {
self.surface.wnoutrefresh()
} else {
Ok(())
}
}
fn register_layer() -> usize {
let stack = PANEL_STACK.get_or_init(|| Mutex::new(Vec::new()));
let mut guard = stack.lock().unwrap();
let id = guard.len();
guard.push(id);
id
}
}
impl Drop for Layer {
fn drop(&mut self) {
let stack = PANEL_STACK.get_or_init(|| Mutex::new(Vec::new()));
let mut guard = stack.lock().unwrap();
if let Some(pos) = guard.iter().position(|&id| id == self.layer_id) {
guard.remove(pos);
}
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_layer_creation() {
let win = Surface::new(10, 20, 5, 5).unwrap();
let layer = Layer::new(win).unwrap();
assert!(!layer.is_hidden());
}
#[test]
fn test_layer_hide_show() {
let win = Surface::new(10, 20, 5, 5).unwrap();
let mut layer = Layer::new(win).unwrap();
assert!(!layer.is_hidden());
layer.hide().unwrap();
assert!(layer.is_hidden());
layer.show().unwrap();
assert!(!layer.is_hidden());
}
#[test]
fn test_layer_surface_access() {
let win = Surface::new(10, 20, 5, 5).unwrap();
let mut layer = Layer::new(win).unwrap();
assert_eq!(layer.surface().get_size(), (10, 20));
assert_eq!(layer.surface().get_position(), (5, 5));
layer
.surface_mut()
.set_foreground(crate::color::Color::RED)
.unwrap();
}
#[test]
fn test_layer_z_order() {
let win1 = Surface::new(10, 20, 0, 0).unwrap();
let win2 = Surface::new(10, 20, 5, 5).unwrap();
let mut layer1 = Layer::new(win1).unwrap();
let mut layer2 = Layer::new(win2).unwrap();
layer1.top().unwrap();
layer2.bottom().unwrap();
assert_eq!(layer1.layer_id, 0);
assert_eq!(layer2.layer_id, 1);
}
}