138 lines
3.9 KiB
Rust
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: >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::<Vec<_>>()),
|
|
};
|
|
process::exit(exit_code);
|
|
}
|