diff --git a/res/main.glade b/res/main.glade
index bd14bfe..e4daa74 100644
--- a/res/main.glade
+++ b/res/main.glade
@@ -7,6 +7,18 @@
False
contact-new-symbolic
+
+
+
-
- True
+
False
- preferences-system-symbolic
-
-
- True
- False
- view-list-bullet-symbolic
- 1
+ True
+ False
+ app
+
+
+
+
+
+ True
+ False
+ 5
+ 5
+ 5
+ 5
+ 5
+
+
+ True
+ True
+ 40
+
+
+ 1
+ 0
+
+
+
+
+ True
+ False
+ end
+ Name
+
+
+ 0
+ 0
+
+
+
+
+ True
+ False
+ start
+ Description
+ end
+
+
+ 0
+ 1
+ 2
+
+
+
+
+ True
+ True
+ 5
+ 5
+ True
+ word
+ pawn_desc
+
+
+ 1
+ 1
+ 2
+
+
+
+
diff --git a/src/main.rs b/src/main.rs
index 994b2cb..791e41e 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -20,8 +20,74 @@ mod pawn;
pub struct AppData {
/// A slot for any pawn waiting for placement
pending: Option,
- /// Owned list of pawns
- pawns: Vec,
+ pawns: Option,
+}
+
+#[derive(Debug,Clone)]
+struct NewPawnDialog {
+ root: gtk::Window,
+ name: gtk::Entry,
+ desc: gtk::TextBuffer,
+ confirm: gtk::Button,
+ abort: gtk::Button,
+}
+
+impl NewPawnDialog {
+
+ fn init(builder: >k::Builder, app_state: AppState) -> Self {
+ let dialog = NewPawnDialog {
+ root: builder.get_object("new_pawn_dialog").unwrap(),
+ name: builder.get_object("name_entry").unwrap(),
+ desc: builder.get_object("pawn_desc").unwrap(),
+ confirm: builder.get_object("confirm").unwrap(),
+ abort: builder.get_object("abort").unwrap(),
+ };
+ let d = dialog.clone();
+ dialog.abort.connect_clicked(move |_| { d.reset(); d.hide(); });
+ let d = dialog.clone();
+ dialog.confirm.connect_clicked(move |_| {
+ if let Some(data) = d.take_data() {
+ let pawn = pawn::Pawn::from_data(data);
+ println!("Create {:?}", pawn);
+ app_state.add_pawn(&pawn);
+ d.reset();
+ d.hide();
+ };
+ });
+ dialog
+ }
+
+ fn reset(&self) {
+ self.name.set_text("");
+ self.desc.set_text("");
+ }
+
+ fn take_data(&self) -> Option {
+ let name = String::from(self.name.get_text().unwrap().as_str());
+ let description = {
+ let (ref start, ref end) = self.desc.get_bounds();
+ String::from(
+ self.desc.get_text(start, end, true).unwrap().as_str()
+ )
+ };
+ if name.is_empty() {
+ None
+ } else {
+ Some(pawn::PawnData {
+ name,
+ description,
+ position: None,
+ })
+ }
+ }
+
+ fn show(&self) {
+ self.root.show_all();
+ }
+
+ fn hide(&self) {
+ self.root.set_visible(false);
+ }
}
/// A sharable state for the whole application
@@ -35,6 +101,20 @@ impl std::ops::Deref for AppState {
}
}
+impl AppState {
+
+ fn add_pawn(&self, pawn: &pawn::Pawn) {
+ pawn.connect_place(self.clone());
+ pawn.connect_stats();
+ self.borrow_mut()
+ .pawns
+ .as_ref()
+ .expect("PawnList was not initialized !")
+ .add(&pawn);
+ dbg!(pawn);
+ }
+}
+
struct App {
inner: gtk::Application,
state: AppState,
@@ -75,12 +155,10 @@ impl App {
// Pawn list
let pawn_list = builder.get_object("pawn_list").unwrap();
let pawn_list = pawn::PawnList::init(pawn_list);
+ app_state.borrow_mut().pawns.replace(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);
+ app_state.add_pawn(&pawn);
}
win.show_all(); // Before grid because we want to hide some widgets there
// Initialize grid
@@ -89,9 +167,17 @@ impl App {
// * 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());
+
+ let dialog = NewPawnDialog::init(&builder, app_state.clone());
+ let new_pawn_btn: gtk::Button = builder.get_object("add_pawn").unwrap();
+ new_pawn_btn.connect_clicked(move |_| { Self::on_add_pawn(&dialog)});
});
}
+ fn on_add_pawn(win: &NewPawnDialog) {
+ win.show();
+ }
+
/// Creates a simple action and connects the given handler to its activate signal.
fn new_action) + 'static>(
app: >k::Application,
diff --git a/src/pawn.rs b/src/pawn.rs
index 4cf6cce..4ed4f6a 100644
--- a/src/pawn.rs
+++ b/src/pawn.rs
@@ -17,6 +17,7 @@ impl PawnList {
let row = gtk::ListBoxRow::new();
row.add(pawn.as_ref());
self.inner.add(&row);
+ self.inner.show_all();
}
}
@@ -24,6 +25,7 @@ impl PawnList {
#[derive(Debug, Clone)]
pub struct PawnData {
pub name: String,
+ pub description: String,
pub position: Option, // Content of label from CellWidget
}
@@ -37,7 +39,7 @@ pub struct Pawn {
}
impl Pawn {
- pub fn new>(name: S) -> Self {
+ pub fn new>(name: S, description: S) -> Self {
let pawn_src = include_str!("../res/pawn.glade");
let builder = gtk::Builder::new_from_string(pawn_src);
let name = name.into();
@@ -47,6 +49,7 @@ impl Pawn {
Pawn {
data: PawnData {
name,
+ description: description.into(),
position: None,
},
widget,
@@ -55,13 +58,16 @@ impl Pawn {
}
}
+ pub fn from_data(data: PawnData) -> Self {
+ Self::new(data.name, data.description)
+ }
+
pub fn connect_place(&self, state: AppState) {
- let name = self.data.name.clone();
let data = self.data.clone();
self.place_btn.connect_clicked(move |_| {
- println!("Placing {}...", name);
+ println!("Placing {}...", &data.name);
let mut state = state.0.borrow_mut();
- state.pending = Some(data.clone()); // ???
+ let _ = state.pending.replace(data.clone()); // ???
});
}
@@ -81,7 +87,7 @@ impl AsRef for Pawn {
pub fn pawn_factory() -> Vec {
let mut pawns = Vec::with_capacity(3);
for name in &["Lomion", "Oilosse", "Fefi"] {
- pawns.push(Pawn::new(*name));
+ pawns.push(Pawn::new(*name, ""));
}
pawns
}