From 6491657ae71c9ff5e96a8daae9bfbcc249ae76b1 Mon Sep 17 00:00:00 2001 From: Niko Abeler Date: Tue, 19 Dec 2023 21:47:34 +0100 Subject: [PATCH] set door as hidden + handle change of active element properly --- src/door.rs | 30 ++++++++++++++++++++++++------ src/state/commands.rs | 5 +++++ src/storage.rs | 12 ++++++++++++ src/view/chamber_edit.rs | 3 +++ src/view/door_edit.rs | 16 +++++++++++++++- 5 files changed, 59 insertions(+), 7 deletions(-) diff --git a/src/door.rs b/src/door.rs index 308c8eb..ee98be0 100644 --- a/src/door.rs +++ b/src/door.rs @@ -60,12 +60,30 @@ impl Door { b: 1.0, }); - vec![Box::new(Line { - color: color, - from: world_pos - (self.width / 2.0) * tangent, - to: world_pos + (self.width / 2.0) * tangent, - width: 20.0, - })] + // TODO: better door visuals + if self.hidden { + vec![ + Box::new(Line { + color: color, + from: world_pos - (self.width / 2.0) * tangent, + to: world_pos + (self.width / 2.0) * tangent, + width: 10.0, + }), + Box::new(Line { + color: color, + from: world_pos - (self.width / 4.0) * tangent, + to: world_pos + (self.width / 4.0) * tangent, + width: 20.0, + }), + ] + } else { + vec![Box::new(Line { + color: color, + from: world_pos - (self.width / 2.0) * tangent, + to: world_pos + (self.width / 2.0) * tangent, + width: 20.0, + })] + } } pub(crate) fn contains_point(&self, wall: &Wall, pos: Vec2) -> bool { diff --git a/src/state/commands.rs b/src/state/commands.rs index f9ae2b7..3fa0d5c 100644 --- a/src/state/commands.rs +++ b/src/state/commands.rs @@ -22,6 +22,7 @@ pub enum StateCommand { ChangeDoorName(DoorId, String), ChangeDoorNotes(DoorId, String), ChangeDoorLeadsTo(DoorId, Option), + ChangeDoorHidden(DoorId, bool), DeleteDoor(DoorId), } @@ -141,6 +142,10 @@ impl StateCommand { state.dungeon.door_mut(*door_id).unwrap().leads_to = *chamber_id; vec![StateEvent::DoorModified(*door_id)] } + StateCommand::ChangeDoorHidden(door_id, hidden) => { + state.dungeon.door_mut(*door_id).unwrap().hidden = *hidden; + vec![StateEvent::DoorModified(*door_id)] + } StateCommand::DeleteDoor(door_id) => { state.dungeon.remove_door(*door_id); let mut events = vec![StateEvent::DoorDeleted(*door_id)]; diff --git a/src/storage.rs b/src/storage.rs index 279cea9..d4a5e09 100644 --- a/src/storage.rs +++ b/src/storage.rs @@ -119,6 +119,13 @@ fn line_to_command(l: &String) -> Option { }, )) } + "ChangeDoorHidden" => { + let v: Value = serde_json::from_str(data).unwrap(); + Some(StateCommand::ChangeDoorHidden( + v["door_id"].as_u64().unwrap() as ChamberId, + v["hidden"].as_bool().unwrap(), + )) + } "DeleteDoor" => { let v: Value = serde_json::from_str(data).unwrap(); Some(StateCommand::DeleteDoor( @@ -179,6 +186,7 @@ pub fn save_to_file(save_file: String, cmds: &Vec) { StateCommand::ChangeDoorName(_, _) => "ChangeDoorName".to_owned(), StateCommand::ChangeDoorNotes(_, _) => "ChangeDoorNotes".to_owned(), StateCommand::ChangeDoorLeadsTo(_, _) => "ChangeDoorLeadsTo".to_owned(), + StateCommand::ChangeDoorHidden(_, _) => "ChangeDoorHidden".to_owned(), StateCommand::DeleteDoor(_) => "DeleteDoor".to_owned(), }; let data = match cmd { @@ -230,6 +238,10 @@ pub fn save_to_file(save_file: String, cmds: &Vec) { "door_id": door_id, "chamber_id": chamber_id, }), + StateCommand::ChangeDoorHidden(door_id, hidden) => json!({ + "door_id": door_id, + "hidden": hidden, + }), StateCommand::DeleteDoor(door_id) => json!({ "door_id": door_id }), }; data_str += format!("{} >> {}\n", name, data).as_str(); diff --git a/src/view/chamber_edit.rs b/src/view/chamber_edit.rs index 0730192..c4e8c92 100644 --- a/src/view/chamber_edit.rs +++ b/src/view/chamber_edit.rs @@ -12,6 +12,7 @@ pub struct ChamberEdit { pub widget: Box, name_input: Entry, notes_input: TextView, + hidden_input: CheckButton, } impl ChamberEdit { @@ -78,6 +79,7 @@ impl ChamberEdit { widget: b, name_input: name_i, notes_input: notes_i, + hidden_input: hidden_i, })); control.borrow_mut().subscribe_any(re.clone()); @@ -98,6 +100,7 @@ impl StateEventSubscriber for ChamberEdit { let chamber = state.dungeon.chamber_mut(chamber_id).unwrap(); self.name_input.set_text(&chamber.name); self.notes_input.buffer().set_text(&chamber.notes); + self.hidden_input.set_active(chamber.hidden); self.widget.set_visible(true); } StateEvent::Reset => self.widget.set_visible(false), diff --git a/src/view/door_edit.rs b/src/view/door_edit.rs index 1dcb113..478e959 100644 --- a/src/view/door_edit.rs +++ b/src/view/door_edit.rs @@ -2,7 +2,7 @@ use std::cell::RefCell; use std::rc::Rc; use gtk::glib::clone; -use gtk::{gio, glib, DropDown, Expression, ListItem, SignalListItemFactory}; +use gtk::{gio, glib, CheckButton, DropDown, Expression, ListItem, SignalListItemFactory}; use gtk::{prelude::*, Label, TextView}; use gtk::{Box, Entry}; @@ -18,6 +18,7 @@ pub struct DoorEdit { name_input: Entry, notes_input: TextView, leads_to_input: DropDown, + hidden_input: CheckButton, chambers_model: gio::ListStore, } @@ -29,6 +30,7 @@ impl DoorEdit { .left_margin(10) .right_margin(10) .build(); + let hidden_i = CheckButton::builder().label("Hidden").build(); let chamber_vec: Vec = vec![ChamberObject::new(None, "-- No Chamber --".to_owned())]; @@ -115,6 +117,15 @@ impl DoorEdit { } })); + hidden_i.connect_toggled( + clone!(@strong control => move |w| if let Ok(mut control) = control.try_borrow_mut() { + match control.state.active_door_id { + None => (), + Some(door_id) => control.apply(StateCommand::ChangeDoorHidden(door_id, w.is_active())), + } + }), + ); + let b = Box::builder() .orientation(gtk::Orientation::Vertical) .build(); @@ -123,6 +134,7 @@ impl DoorEdit { b.append(&part_of_label); b.append(&Label::new(Some("Name"))); b.append(&name_i); + b.append(&hidden_i); b.append(&Label::new(Some("Notes"))); b.append(¬es_i); b.append(&Label::new(Some("Leads to Chamber:"))); @@ -136,6 +148,7 @@ impl DoorEdit { name_input: name_i, notes_input: notes_i, leads_to_input: leads_to_i, + hidden_input: hidden_i, chambers_model: model, })); @@ -177,6 +190,7 @@ impl StateEventSubscriber for DoorEdit { self.notes_input.buffer().set_text(&door.notes); self.leads_to_input .set_selected(self.chamber_object_pos(door.leads_to)); + self.hidden_input.set_active(door.hidden); self.widget.set_visible(true); } StateEvent::Reset => self.widget.set_visible(false),