Files
playmat/src/main.rs
2019-06-06 16:36:10 +02:00

138 lines
3.9 KiB
Rust

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<pawn::PawnData>,
/// Owned list of pawns
pawns: Vec<pawn::Pawn>,
}
/// A sharable state for the whole application
#[derive(Debug,Clone,Default)]
pub struct AppState(Rc<RefCell<AppData>>);
impl std::ops::Deref for AppState {
type Target = Rc<RefCell<AppData>>;
fn deref(&self) -> &Self::Target {
&self.0
}
}
struct App {
inner: gtk::Application,
state: AppState,
}
impl App {
fn new<'a>() -> Result<Self, &'a str> {
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<F: Fn(&gio::SimpleAction, &Option<glib::Variant>) + 'static>(
app: &gtk::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::<Vec<_>>()),
};
process::exit(exit_code);
}