extern crate gtk; extern crate gio; extern crate gdk; extern crate glib; use std::cell::RefCell; use std::rc::Rc; use gtk::prelude::*; use gio::prelude::*; use std::env::args; use std::process; mod grid; mod pawn; /// Content of the Application state /// #[derive(Debug,Clone,Default)] pub struct AppData { /// A slot for any pawn waiting for placement pending: Option, /// Owned list of pawns pawns: Vec, } /// A sharable state for the whole application #[derive(Debug,Clone,Default)] pub struct AppState(Rc>); impl std::ops::Deref for AppState { type Target = Rc>; fn deref(&self) -> &Self::Target { &self.0 } } struct App { inner: gtk::Application, state: AppState, } impl App { fn new<'a>() -> Result { let app = App { inner: gtk::Application::new( "home.local.PlayMat", gio::ApplicationFlags::FLAGS_NONE ).expect("Failed to build Application"), state: Default::default(), }; app.connect_all(); Ok(app) } fn connect_all(&self) { let app_state = self.state.clone(); self.inner.connect_startup(|_| {}); self.inner.connect_activate( move |app| { println!("Activate App"); let main_src = "/home/artus/Projets/rust/playmat/res/main.glade"; let builder = gtk::Builder::new_from_file(main_src); let win: gtk::ApplicationWindow = builder .get_object("app") .unwrap(); win.set_application(app); // Set up a simple switch for the Pawn list panel let panel: gtk::Paned = builder.get_object("panel").unwrap(); Self::new_action(app, "panel_switch", move |_,_| { if panel.get_position() == 0 { panel.set_position(360); } else { panel.set_position(0); } }); // Initialize grid let grid: gtk::Grid = builder.get_object("map").unwrap(); // TODO: implement drag-drop events // * From pawn_list to cell : place pawn on dest cell // * From cell to cell : move pawn from source to dest cell let _grid = grid::Grid::init(grid, 10, app_state.clone()); // TODO: // * Display creature description when hovering over its position (cell) // TODO: Pawn list let pawn_list = builder.get_object("pawn_list").unwrap(); let pawn_list = pawn::PawnList::init(pawn_list); for pawn in pawn::pawn_factory() { pawn_list.add(&pawn); pawn.connect_place(app_state.clone()); pawn.connect_stats(); app_state.borrow_mut().pawns.push(pawn); } win.show_all(); } ); } /// Creates a simple action and connects the given handler to its activate signal. fn new_action) + 'static>( app: >k::Application, name: &str, f: F, ) { let action = gio::SimpleAction::new(name, None); action.connect_activate(f); app.add_action(&action); } fn run(&self, args: &[String]) -> i32 { println!("{:#?}", &self.state); self.inner.run(args) } } fn main() { if gtk::init().is_err() { println!("Failed to initialize Gtk"); return } let exit_code = match App::new() { Err(e) => { println!("Error !\n{}", e); 1 }, Ok(app) => app.run(&args().collect::>()), }; process::exit(exit_code); }