149 lines
3.8 KiB
Rust
149 lines
3.8 KiB
Rust
//! Map editor interface.
|
|
|
|
use super::glib::*;
|
|
use gobject_sys::*;
|
|
use gtk_sys::*;
|
|
use maraiah::{durandal::ffi, marathon::map, rozinante::editor};
|
|
|
|
fn each_flag<T, F>(buttons: &[PropFlag], ordering: &[T], mut f: F)
|
|
where F: FnMut(&PropFlag, &T)
|
|
{
|
|
for (flg, ord) in buttons.iter().zip(ordering) {
|
|
f(flg, ord);
|
|
}
|
|
}
|
|
|
|
fn refresh_flags<T, F>(mut f: F) -> impl FnMut(&PropFlag, &T)
|
|
where F: FnMut(&T) -> bool
|
|
{
|
|
move |flg, ord| {
|
|
unsafe {
|
|
g_signal_handler_block(*flg.w as _, flg.h);
|
|
|
|
gtk_toggle_button_set_active(*flg.w, f(ord).into());
|
|
|
|
g_signal_handler_unblock(*flg.w as _, flg.h);
|
|
}
|
|
}
|
|
}
|
|
|
|
fn set_flags<T, F>(mut f: F) -> impl FnMut(&PropFlag, &T)
|
|
where F: FnMut(&T, bool)
|
|
{
|
|
move |flg, ord| f(ord, unsafe {gtk_toggle_button_get_active(*flg.w)} != 0)
|
|
}
|
|
|
|
impl MapEditor
|
|
{
|
|
/// Propagates all updated map information to widgets.
|
|
pub fn cause_refresh(&self)
|
|
{
|
|
self.cause_refresh_view();
|
|
self.cause_refresh_props();
|
|
}
|
|
|
|
/// Propagates updated map view information to widgets.
|
|
pub fn cause_refresh_view(&self)
|
|
{
|
|
unsafe {
|
|
gtk_widget_queue_draw(*self.draw);
|
|
}
|
|
}
|
|
|
|
/// Propagates updated map property information to widgets.
|
|
pub fn cause_refresh_props(&self)
|
|
{
|
|
let inf = &self.cur_block().info;
|
|
|
|
each_flag(&self.fent, &O_ENT, refresh_flags(|&f| inf.entr_flags.contains(f)));
|
|
each_flag(&self.fenv, &O_ENV, refresh_flags(|&f| inf.envi_flags.contains(f)));
|
|
each_flag(&self.fmsn, &O_MSN, refresh_flags(|&f| inf.miss_flags.contains(f)));
|
|
}
|
|
|
|
/// Propagates updated map property information to the editor state.
|
|
pub fn cause_update_props(&mut self)
|
|
{
|
|
let mut blk = self.cur_block().clone();
|
|
let inf = &mut blk.info;
|
|
|
|
each_flag(&self.fent, &O_ENT, set_flags(|&f, s| inf.entr_flags.set(f, s)));
|
|
each_flag(&self.fenv, &O_ENV, set_flags(|&f, s| inf.envi_flags.set(f, s)));
|
|
each_flag(&self.fmsn, &O_MSN, set_flags(|&f, s| inf.miss_flags.set(f, s)));
|
|
|
|
self.push_block(blk);
|
|
self.cause_refresh_view();
|
|
}
|
|
}
|
|
|
|
impl std::ops::Deref for MapEditor
|
|
{
|
|
type Target = editor::MapEditor;
|
|
|
|
#[inline]
|
|
fn deref(&self) -> &Self::Target {&self.edit}
|
|
}
|
|
|
|
impl std::ops::DerefMut for MapEditor
|
|
{
|
|
#[inline]
|
|
fn deref_mut(&mut self) -> &mut Self::Target {&mut self.edit}
|
|
}
|
|
|
|
/// Specialized map editor which has callbacks for frontend purposes.
|
|
pub struct MapEditor
|
|
{
|
|
pub edit: editor::MapEditor,
|
|
pub draw: Refc<'static, GtkWidget>,
|
|
pub fent: Vec<PropFlag>,
|
|
pub fenv: Vec<PropFlag>,
|
|
pub fmsn: Vec<PropFlag>,
|
|
}
|
|
|
|
/// A runtime reference to the map editor.
|
|
pub type MapEditorRef = std::cell::RefCell<MapEditor>;
|
|
|
|
pub struct PropFlag
|
|
{
|
|
pub w: Refc<'static, GtkToggleButton>,
|
|
pub h: ffi::c_ulong,
|
|
}
|
|
|
|
// NOTE: this is flipped because of GTK weirdness. don't touch
|
|
const O_ENT: [map::minf::EntFlags; 8] = [
|
|
map::minf::EntFlags::CTF,
|
|
map::minf::EntFlags::RUGBY,
|
|
map::minf::EntFlags::DEFENSE,
|
|
map::minf::EntFlags::KOTH,
|
|
map::minf::EntFlags::KTMWTB,
|
|
map::minf::EntFlags::CARNAGE,
|
|
map::minf::EntFlags::CO_OP,
|
|
map::minf::EntFlags::SOLO,
|
|
];
|
|
|
|
const O_ENV: [map::minf::EnvFlags; 11] = [
|
|
map::minf::EnvFlags::VACUUM,
|
|
map::minf::EnvFlags::MAGNETIC,
|
|
map::minf::EnvFlags::REBELLION,
|
|
map::minf::EnvFlags::LOW_GRAV,
|
|
map::minf::EnvFlags::M1_GLUE,
|
|
map::minf::EnvFlags::LAVA_FLOOR,
|
|
map::minf::EnvFlags::REBELLION2,
|
|
map::minf::EnvFlags::MUSIC,
|
|
map::minf::EnvFlags::TERM_PAUSE,
|
|
map::minf::EnvFlags::M1_MONSTER,
|
|
map::minf::EnvFlags::M1_WEPS,
|
|
];
|
|
|
|
const O_MSN: [map::minf::MsnFlags; 8] = [
|
|
map::minf::MsnFlags::EXTERMINATION,
|
|
map::minf::MsnFlags::EXPLORATION,
|
|
map::minf::MsnFlags::RETRIEVAL,
|
|
map::minf::MsnFlags::REPAIR,
|
|
map::minf::MsnFlags::RESCUE,
|
|
map::minf::MsnFlags::M1_EXPLORATION,
|
|
map::minf::MsnFlags::M1_RESCUE,
|
|
map::minf::MsnFlags::M1_REPAIR,
|
|
];
|
|
|
|
// EOF
|