use qualia::{Position, Size, Vector};
use qualia::{SurfaceAccess, surface_state};
use frame::{Frame, Geometry, Mobility};
pub trait Packing {
fn relax(&mut self, sa: &mut SurfaceAccess);
fn homogenize(&mut self, sa: &mut SurfaceAccess);
fn change_size(&mut self, vactor: Vector, sa: &mut SurfaceAccess);
fn set_size(&mut self, size: Size, sa: &mut SurfaceAccess);
fn remove_self(&mut self, sa: &mut SurfaceAccess);
}
impl Packing for Frame {
fn relax(&mut self, sa: &mut SurfaceAccess) {
self.homogenize(sa);
}
fn homogenize(&mut self, sa: &mut SurfaceAccess) {
let len = self.count_anchored_children();
if len < 1 {
return;
}
let mut size = Size::new(0, 0);
let mut increment = Vector::new(0, 0);
match self.get_geometry() {
Geometry::Stacked => {
size = self.get_size();
}
Geometry::Vertical => {
let mut docked_height = 0;
for frame in self.space_iter() {
if frame.get_mobility().is_docked() {
docked_height += frame.get_size().height;
}
}
size.width = self.get_size().width;
size.height = (self.get_size().height - docked_height) / len;
increment.y = size.height as isize;
}
Geometry::Horizontal => {
let mut docked_width = 0;
for frame in self.space_iter() {
if frame.get_mobility().is_docked() {
docked_width += frame.get_size().width;
}
}
size.height = self.get_size().height;
size.width = (self.get_size().width - docked_width) / len;
increment.x = size.width as isize;
}
}
let mut pos = Position::default();
for mut frame in self.space_iter() {
match frame.get_mobility() {
Mobility::Anchored => {
frame.set_size(size, sa);
frame.set_plumbing_position(pos);
pos = pos + increment;
}
Mobility::Docked => {
match self.get_geometry() {
Geometry::Stacked => {}
Geometry::Vertical => pos.y += frame.get_size().height as isize,
Geometry::Horizontal => pos.x += frame.get_size().width as isize,
}
}
Mobility::Floating => {}
}
}
}
fn change_size(&mut self, vector: Vector, sa: &mut SurfaceAccess) {
let size = self.get_size().sized(vector);
self.set_size(size, sa);
}
fn set_size(&mut self, size: Size, sa: &mut SurfaceAccess) {
let old_size = self.get_size();
self.set_plumbing_size(size.clone());
sa.reconfigure(self.get_sid(), size.clone(), surface_state::MAXIMIZED);
match self.get_geometry() {
Geometry::Horizontal => {
if old_size.width == size.width {
for mut frame in self.space_iter() {
let mut frame_size = frame.get_size();
frame_size.height = size.height;
frame.set_size(frame_size, sa);
}
} else {
self.relax(sa);
}
}
Geometry::Vertical => {
if old_size.height == size.height {
for mut frame in self.space_iter() {
let mut frame_size = frame.get_size();
frame_size.width = size.width;
frame.set_size(frame_size, sa);
}
} else {
self.relax(sa);
}
}
Geometry::Stacked => {
for mut frame in self.space_iter() {
if !frame.get_mobility().is_floating() {
frame.set_size(size.clone(), sa);
}
}
}
}
}
fn remove_self(&mut self, sa: &mut SurfaceAccess) {
if let Some(ref mut parent) = self.get_parent() {
self.remove();
let len = parent.count_children();
if len == 0 && !parent.is_top() {
parent.remove_self(sa);
} else {
parent.relax(sa);
}
}
}
}