extern crate gtk; use gtk::*; use std::process; use std::sync::atomic::{ AtomicUsize, Ordering }; use std::sync::Arc; // TODO listen for connect_delete_event pub struct App { pub window: Window, pub header: Header, pub content: Content, } pub struct Header { pub container: HeaderBar, pub reset: Button, } pub struct Content { pub container: Box, pub add: Button, pub counter: Label, } pub struct Counter(AtomicUsize); impl App { fn new(counter: &Counter) -> App { let window = Window::new(WindowType::Toplevel); let header = Header::new(); let content = Content::new(counter); // Define windows stuff window.set_titlebar(&header.container); window.set_title("Hello world!"); window.set_wmclass("test-app", "test app"); Window::set_default_icon_name("iconname"); window.add(&content.container); window.connect_delete_event(move |_, _| { main_quit(); Inhibit(false) }); App { window, header, content} } } impl Content { fn new(counter: &Counter) -> Content { let container = Box::new(Orientation::Horizontal, 0); let counter = Label::new(counter.get_count().to_string().as_str()); let add = Button::new_with_label("Add"); add.get_style_context().map(|c| c.add_class("suggested-action")); container.pack_start(&counter, true, true, 0); container.pack_start(&add, false, false, 0); Content { container, counter, add} } } impl Header { fn new() -> Header { let container = HeaderBar::new(); let reset = Button::new_with_label("Reset"); container.set_title("Hello world!"); container.set_show_close_button(true); reset.get_style_context().map(|c| c.add_class("destructive-action")); container.pack_start(&reset); Header { container, reset } } } impl Counter { fn new() -> Counter { Counter(AtomicUsize::new(0)) } fn get_count(&self) -> usize { self.0.load(Ordering::SeqCst) } fn reset(&self) { self.0.store(0, Ordering::SeqCst); } fn count(&self) -> usize { let before = self.0.fetch_add(1, Ordering::SeqCst); before + 1 } } fn main() { println!("Hello, world!"); let c = Arc::new(Counter::new()); if gtk::init().is_err() { eprintln!("failed to init GTK"); process::exit(1); } let app = App::new(&c); { let counter = c.clone(); let info = app.content.counter.clone(); app.header.reset.clone().connect_clicked(move |_| { counter.reset(); info.set_label("0"); }); } { let counter = c.clone(); let info = app.content.counter.clone(); app.content.add.clone().connect_clicked(move |_| { let new = counter.count(); info.set_label(new.to_string().as_str()); }); } app.window.show_all(); gtk::main(); }