adds pawn creation

This commit is contained in:
2019-06-08 15:25:01 +02:00
parent b2d372f8a7
commit a1412f03d2
3 changed files with 214 additions and 21 deletions

View File

@@ -7,6 +7,18 @@
<property name="can_focus">False</property>
<property name="icon_name">contact-new-symbolic</property>
</object>
<object class="GtkImage" id="image1">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="icon_name">preferences-system-symbolic</property>
</object>
<object class="GtkTextBuffer" id="pawn_desc"/>
<object class="GtkImage" id="show_list_img">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="icon_name">view-list-bullet-symbolic</property>
<property name="icon_size">1</property>
</object>
<object class="GtkApplicationWindow" id="app">
<property name="can_focus">False</property>
<property name="events">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</property>
@@ -40,7 +52,7 @@
</packing>
</child>
<child>
<object class="GtkButton" id="add_btn">
<object class="GtkButton" id="add_pawn">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
@@ -160,15 +172,104 @@
</object>
</child>
</object>
<object class="GtkImage" id="image1">
<property name="visible">True</property>
<object class="GtkWindow" id="new_pawn_dialog">
<property name="can_focus">False</property>
<property name="icon_name">preferences-system-symbolic</property>
</object>
<object class="GtkImage" id="show_list_img">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="icon_name">view-list-bullet-symbolic</property>
<property name="icon_size">1</property>
<property name="modal">True</property>
<property name="deletable">False</property>
<property name="transient_for">app</property>
<child type="titlebar">
<object class="GtkHeaderBar">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="title" translatable="yes">Ajouter un personnage</property>
<child>
<object class="GtkButton" id="confirm">
<property name="label">gtk-apply</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="use_stock">True</property>
<property name="always_show_image">True</property>
</object>
</child>
<child>
<object class="GtkButton" id="abort">
<property name="label">gtk-cancel</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="use_stock">True</property>
<property name="always_show_image">True</property>
</object>
<packing>
<property name="position">1</property>
</packing>
</child>
</object>
</child>
<child>
<object class="GtkGrid">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="margin_left">5</property>
<property name="margin_right">5</property>
<property name="margin_top">5</property>
<property name="margin_bottom">5</property>
<property name="row_spacing">5</property>
<child>
<object class="GtkEntry" id="name_entry">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="width_chars">40</property>
</object>
<packing>
<property name="left_attach">1</property>
<property name="top_attach">0</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="name_label">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="halign">end</property>
<property name="label" translatable="yes">Name</property>
</object>
<packing>
<property name="left_attach">0</property>
<property name="top_attach">0</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="desc_label">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="valign">start</property>
<property name="label" translatable="yes">Description</property>
<property name="ellipsize">end</property>
</object>
<packing>
<property name="left_attach">0</property>
<property name="top_attach">1</property>
<property name="height">2</property>
</packing>
</child>
<child>
<object class="GtkTextView" id="desc_entry">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="margin_top">5</property>
<property name="margin_bottom">5</property>
<property name="vexpand">True</property>
<property name="wrap_mode">word</property>
<property name="buffer">pawn_desc</property>
</object>
<packing>
<property name="left_attach">1</property>
<property name="top_attach">1</property>
<property name="height">2</property>
</packing>
</child>
</object>
</child>
</object>
</interface>

View File

@@ -20,8 +20,74 @@ mod pawn;
pub struct AppData {
/// A slot for any pawn waiting for placement
pending: Option<pawn::PawnData>,
/// Owned list of pawns
pawns: Vec<pawn::Pawn>,
pawns: Option<pawn::PawnList>,
}
#[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: &gtk::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<pawn::PawnData> {
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<F: Fn(&gio::SimpleAction, &Option<glib::Variant>) + 'static>(
app: &gtk::Application,

View File

@@ -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<String>, // Content of label from CellWidget
}
@@ -37,7 +39,7 @@ pub struct Pawn {
}
impl Pawn {
pub fn new<S: Into<String>>(name: S) -> Self {
pub fn new<S: Into<String>>(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<gtk::Box> for Pawn {
pub fn pawn_factory() -> Vec<Pawn> {
let mut pawns = Vec::with_capacity(3);
for name in &["Lomion", "Oilosse", "Fefi"] {
pawns.push(Pawn::new(*name));
pawns.push(Pawn::new(*name, ""));
}
pawns
}