commit ca3696f63f47e62234e9ce0265d17a73576d37b8 Author: Artus Date: Mon Jun 3 14:59:52 2019 +0200 first steps diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..f534602 --- /dev/null +++ b/.gitignore @@ -0,0 +1,6 @@ +/target +**/*.rs.bk + +Cargo.lock + +**/*.glade~ diff --git a/Cargo.toml b/Cargo.toml new file mode 100644 index 0000000..2d398c3 --- /dev/null +++ b/Cargo.toml @@ -0,0 +1,14 @@ +[package] +name = "playmat" +version = "0.1.0" +authors = ["Artus "] +edition = "2018" + +[dependencies] +gio = "*" +gdk = "*" +glib = "*" + +[dependencies.gtk] +version = "^0.6.0" +features = ["v3_22"] diff --git a/res/cell.glade b/res/cell.glade new file mode 100644 index 0000000..e19ede2 --- /dev/null +++ b/res/cell.glade @@ -0,0 +1,77 @@ + + + + + + True + False + + + + + True + False + 3 + 3 + 2 + 0.94999998807907104 + 0.20000000298023224 + in + + + 128 + 128 + True + False + vertical + + + True + False + GDK_EXPOSURE_MASK | GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_MOTION_MASK | GDK_BUTTON1_MOTION_MASK | GDK_BUTTON2_MOTION_MASK | GDK_BUTTON3_MOTION_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | GDK_KEY_PRESS_MASK | GDK_KEY_RELEASE_MASK | GDK_ENTER_NOTIFY_MASK | GDK_LEAVE_NOTIFY_MASK | GDK_FOCUS_CHANGE_MASK | GDK_STRUCTURE_MASK | GDK_PROPERTY_CHANGE_MASK | GDK_VISIBILITY_NOTIFY_MASK | GDK_PROXIMITY_IN_MASK | GDK_PROXIMITY_OUT_MASK | GDK_SUBSTRUCTURE_MASK | GDK_SCROLL_MASK | GDK_TOUCH_MASK | GDK_SMOOTH_SCROLL_MASK | GDK_TOUCHPAD_GESTURE_MASK | GDK_TABLET_PAD_MASK + Cell + right + + + + + + + False + True + 0 + + + + + True + False + Occupancy + Status + + + True + True + 1 + + + + + + + True + False + _x_ + + + + + + + + + + + + + diff --git a/res/main.glade b/res/main.glade new file mode 100644 index 0000000..4d96df4 --- /dev/null +++ b/res/main.glade @@ -0,0 +1,123 @@ + + + + + + False + GDK_EXPOSURE_MASK | GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_MOTION_MASK | GDK_BUTTON1_MOTION_MASK | GDK_BUTTON2_MOTION_MASK | GDK_BUTTON3_MOTION_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | GDK_KEY_PRESS_MASK | GDK_KEY_RELEASE_MASK | GDK_ENTER_NOTIFY_MASK | GDK_LEAVE_NOTIFY_MASK | GDK_FOCUS_CHANGE_MASK | GDK_STRUCTURE_MASK | GDK_PROPERTY_CHANGE_MASK | GDK_VISIBILITY_NOTIFY_MASK | GDK_PROXIMITY_IN_MASK | GDK_PROXIMITY_OUT_MASK | GDK_SUBSTRUCTURE_MASK | GDK_SCROLL_MASK | GDK_TOUCH_MASK | GDK_SMOOTH_SCROLL_MASK | GDK_TOUCHPAD_GESTURE_MASK | GDK_TABLET_PAD_MASK + + + True + False + Play Mat + version 0.1 + True + + + Créatures + True + True + True + app.panel_switch + + + + + + + True + True + 80 + + + True + False + + + 100 + 80 + True + True + + + + + + + + False + True + + + + + True + True + GDK_EXPOSURE_MASK | GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_MOTION_MASK | GDK_BUTTON1_MOTION_MASK | GDK_BUTTON2_MOTION_MASK | GDK_BUTTON3_MOTION_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | GDK_KEY_PRESS_MASK | GDK_KEY_RELEASE_MASK | GDK_ENTER_NOTIFY_MASK | GDK_LEAVE_NOTIFY_MASK | GDK_FOCUS_CHANGE_MASK | GDK_STRUCTURE_MASK | GDK_PROPERTY_CHANGE_MASK | GDK_VISIBILITY_NOTIFY_MASK | GDK_PROXIMITY_IN_MASK | GDK_PROXIMITY_OUT_MASK | GDK_SUBSTRUCTURE_MASK | GDK_SCROLL_MASK | GDK_TOUCH_MASK | GDK_SMOOTH_SCROLL_MASK | GDK_TOUCHPAD_GESTURE_MASK | GDK_TABLET_PAD_MASK + 10 + 10 + 10 + 10 + out + 640 + 480 + 800 + 600 + True + True + + + True + False + GDK_EXPOSURE_MASK | GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_MOTION_MASK | GDK_BUTTON1_MOTION_MASK | GDK_BUTTON2_MOTION_MASK | GDK_BUTTON3_MOTION_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | GDK_KEY_PRESS_MASK | GDK_KEY_RELEASE_MASK | GDK_ENTER_NOTIFY_MASK | GDK_LEAVE_NOTIFY_MASK | GDK_FOCUS_CHANGE_MASK | GDK_STRUCTURE_MASK | GDK_PROPERTY_CHANGE_MASK | GDK_VISIBILITY_NOTIFY_MASK | GDK_PROXIMITY_IN_MASK | GDK_PROXIMITY_OUT_MASK | GDK_SUBSTRUCTURE_MASK | GDK_SCROLL_MASK | GDK_TOUCH_MASK | GDK_SMOOTH_SCROLL_MASK | GDK_TOUCHPAD_GESTURE_MASK | GDK_TABLET_PAD_MASK + etched-in + + + True + False + GDK_EXPOSURE_MASK | GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_MOTION_MASK | GDK_BUTTON1_MOTION_MASK | GDK_BUTTON2_MOTION_MASK | GDK_BUTTON3_MOTION_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | GDK_KEY_PRESS_MASK | GDK_KEY_RELEASE_MASK | GDK_ENTER_NOTIFY_MASK | GDK_LEAVE_NOTIFY_MASK | GDK_FOCUS_CHANGE_MASK | GDK_STRUCTURE_MASK | GDK_PROPERTY_CHANGE_MASK | GDK_VISIBILITY_NOTIFY_MASK | GDK_PROXIMITY_IN_MASK | GDK_PROXIMITY_OUT_MASK | GDK_SUBSTRUCTURE_MASK | GDK_SCROLL_MASK | GDK_TOUCH_MASK | GDK_SMOOTH_SCROLL_MASK | GDK_TOUCHPAD_GESTURE_MASK | GDK_TABLET_PAD_MASK + center + center + True + True + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + False + True + + + + + + diff --git a/src/grid.rs b/src/grid.rs new file mode 100644 index 0000000..20fe45e --- /dev/null +++ b/src/grid.rs @@ -0,0 +1,104 @@ +use crate::*; + +pub struct Grid { + inner: gtk::Grid, +} + +pub struct CellPosition(i32, i32); + +impl Grid { + // Initialize a grid, populating its cells + // Only square grid for now + pub fn init(inner: gtk::Grid, size: i32) -> Self { + for i in 0..(size * size) { + let x = i % size; + let y = i / size; + let cell = grid::Cell::new(CellPosition(x,y)); + inner.attach(cell.as_ref(), x, y, 1, 1); + // Signals + } + Grid { inner } + } +} + + +struct CellWidget { + eventbox: gtk::EventBox, + position: gtk::Label, + header : gtk::Label, +} + +impl CellWidget { + fn new(pos: CellPosition, header_text: &str) -> Self { + let cell_src = include_str!("../res/cell.glade"); + let builder = gtk::Builder::new_from_string(&cell_src); + + let eventbox: gtk::EventBox = + builder + .get_object("cell") + .unwrap(); + eventbox.set_events(gdk::EventMask::BUTTON_PRESS_MASK); + + let header: gtk::Label = + builder + .get_object("header") + .unwrap(); + header.set_text(header_text); + let position: gtk::Label = + builder + .get_object("position") + .unwrap(); + position.set_text(&format!("{}x{}", pos.0, pos.1)); + + let header_clone = header.clone(); + eventbox.connect_button_press_event(Self::on_click(header_clone)); + + CellWidget { + eventbox, + position, + header, + } + } + + // Handler for button press events + fn on_click( + data: gtk::Label + ) -> impl Fn(>k::EventBox, &gdk::EventButton) -> gtk::Inhibit + { + move |_,_| { + data.set_text("Clicked."); + gtk::Inhibit(true) + } + } +} + +impl AsRef for CellWidget { + #[inline] + fn as_ref(&self) -> >k::EventBox { + &self.eventbox + } +} + +pub struct Cell { + inner: CellWidget, + is_active: bool, + is_occupied: bool, +} + +impl Cell { + pub fn new(pos: CellPosition) -> Self { + let inner = CellWidget::new(pos, "Empty cell"); + Cell { + inner, + is_active: false, + is_occupied: false, + } + } +} + +impl AsRef for Cell { + #[inline] + fn as_ref(&self) -> >k::EventBox { + self.inner.as_ref() + } +} diff --git a/src/main.rs b/src/main.rs new file mode 100644 index 0000000..5ad11c9 --- /dev/null +++ b/src/main.rs @@ -0,0 +1,119 @@ +extern crate gtk; +extern crate gio; +extern crate gdk; +extern crate glib; + +use gtk::BoxExt; +use gtk::prelude::*; +use gio::prelude::*; +use std::env::args; +use std::process; + +mod grid; + +mod pawn { + + pub struct Pawn { + name: String + } + + fn pawn_factory() -> Vec { + let mut pawns = Vec::with_capacity(3); + for name in &["Lomion", "Oilosse", "Fefi"] { + pawns.push(Pawn{ name: name.to_string() }); + } + pawns + } + + #[cfg(test)] + mod tests { + #[test] + fn test_pawn_factory() {} + } +} + + +struct App { + inner: gtk::Application, + pawns: Vec, +} + +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"), + pawns: Vec::new(), + }; + app.inner.connect_startup(|_| {}); + app.inner.connect_activate(Self::on_activate); + Ok(app) + } + + fn on_activate(app: >k::Application) { + println!("Activate App"); + let main_src = include_str!("../res/main.glade"); + let builder = gtk::Builder::new_from_string(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); + + // TODO: + // * Display creature description when hovering over its position (cell) + + // TODO: Pawn list + win.show_all(); + } + + /// Creates a simple action and connects the given handler to its activate signal. + pub 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 { + 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); +}