use super::menu;
use super::widget;
use super::wish;
#[derive(Clone, Debug, PartialEq)]
pub struct TkTopLevel {
pub id: String,
}
pub fn make_toplevel(parent: &impl widget::TkWidget) -> TkTopLevel {
let id = wish::next_wid(parent.id());
let msg = format!("toplevel {}", id);
wish::tell_wish(&msg);
TkTopLevel { id }
}
impl widget::TkWidget for TkTopLevel {
fn id(&self) -> &str {
&self.id
}
}
impl TkTopLevel {
pub fn background(&self, colour: &str) {
widget::configure(&self.id, "background", colour);
}
pub fn border_width(&self, width: u64) {
widget::configure(&self.id, "borderwidth", &width.to_string());
}
pub fn deiconify(&self) {
let msg = format!("wm deiconify {}", self.id);
wish::tell_wish(&msg);
}
pub fn full_screen(&self) {
let msg = format!("wm attributes {} -fullscreen 1", self.id);
wish::tell_wish(&msg);
}
pub fn geometry_get(&self) -> (u64, u64, u64, u64) {
let msg = format!("puts [wm geometry {}] ; flush stdout", self.id);
let result = wish::ask_wish(&msg);
string_geometry(&result)
}
pub fn geometry(&self, width: u64, height: u64, x: i64, y: i64) {
let msg = format!(
"wm geometry {} {}x{}{}{}{}{}",
self.id,
width,
height,
if x < 0 { "-" } else { "+" },
x.abs(),
if y < 0 { "-" } else { "+" },
y.abs()
);
wish::tell_wish(&msg);
}
pub fn height(&self, height: u64) {
widget::configure(&self.id, "height", &height.to_string());
}
pub fn iconify(&self) {
let msg = format!("wm iconify {}", self.id);
wish::tell_wish(&msg);
}
pub fn maximum_size(&self, width: u64, height: u64) {
let msg = format!("wm maxsize {} {} {}", self.id, width, height);
wish::tell_wish(&msg);
}
pub fn menu(&self, menu: &menu::TkMenu) {
widget::configure(&self.id, "menu", &menu.id);
}
pub fn minimum_size(&self, width: u64, height: u64) {
let msg = format!("wm minsize {} {} {}", self.id, width, height);
wish::tell_wish(&msg);
}
pub fn on_close(&self, command: impl Fn() + Send + 'static) {
wish::add_callback0(&self.id, wish::mk_callback0(command));
let msg = format!(
"wm protocol {} WM_DELETE_WINDOW {{ puts clicked-{} ; flush stdout }}",
self.id, self.id
);
wish::tell_wish(&msg);
}
pub fn padx(&self, value: u64) {
widget::configure(&self.id, "padx", &value.to_string());
}
pub fn pady(&self, value: u64) {
widget::configure(&self.id, "pady", &value.to_string());
}
pub fn relief(&self, value: widget::Relief) {
widget::configure(&self.id, "relief", &value.to_string());
}
pub fn resizable(&self, width: bool, height: bool) {
let msg = format!(
"wm resizable {} {} {}",
self.id,
if width { "1" } else { "0" },
if height { "1" } else { "0" }
);
wish::tell_wish(&msg);
}
pub fn title(&self, title: &str) {
let msg = format!("wm title {} {{{}}}\n", self.id, title);
wish::tell_wish(&msg);
}
pub fn update_idle_tasks(&self) {
wish::tell_wish("update idletasks");
}
pub fn width(&self, width: u64) {
widget::configure(&self.id, "width", &width.to_string());
}
pub fn withdraw(&self) {
let msg = format!("wm withdraw {}", self.id);
wish::tell_wish(&msg);
}
pub fn border(&self, value: bool) {
wish::tell_wish(&format!("wm overrideredirect {} {};", &self.id, !value));
}
pub fn topmost(&self, value: bool) {
wish::tell_wish(&format!("wm attributes {} -topmost {};", &self.id, value));
}
pub fn position(&self, x: u64, y: u64) {
wish::tell_wish(&format!("wm geometry {} +{}+{}", &self.id, x, y));
}
}
fn string_geometry(text: &str) -> (u64, u64, u64, u64) {
let parts: Vec<&str> = text.split(&['x', '+'][..]).collect();
let mut w = 0;
let mut h = 0;
let mut x = 0;
let mut y = 0;
if parts.len() == 4 {
w = parts[0].parse::<u64>().unwrap_or(0);
h = parts[1].parse::<u64>().unwrap_or(0);
x = parts[2].parse::<u64>().unwrap_or(0);
y = parts[3].parse::<u64>().unwrap_or(0);
}
(w, h, x, y)
}
#[cfg(test)]
mod tests {
use super::string_geometry;
#[test]
fn geometry() {
assert_eq!((0, 0, 0, 0), string_geometry("0x0+0+0"));
assert_eq!((10, 20, 100, 200), string_geometry("10x20+100+200"));
assert_eq!((0, 0, 0, 0), string_geometry("0x00+0"));
assert_eq!((0, 0, 0, 0), string_geometry(""));
assert_eq!((0, 0, 0, 0), string_geometry("axbxcxd"));
}
}