dynamic safe borrowing of map editor references
parent
3f3900d91c
commit
9542592027
|
@ -17,11 +17,11 @@ impl MapEditor
|
||||||
MapEditor::Closed
|
MapEditor::Closed
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Creates a new empty map.
|
/// Opens the editor with a new empty map.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn new_opened() -> Self
|
pub fn open_new(&mut self)
|
||||||
{
|
{
|
||||||
MapEditor::Opened(MapEditorState::default())
|
*self = MapEditor::Opened(MapEditorState::default());
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Draws the screen for this editor state.
|
/// Draws the screen for this editor state.
|
||||||
|
@ -31,17 +31,23 @@ impl MapEditor
|
||||||
{
|
{
|
||||||
match self {
|
match self {
|
||||||
MapEditor::Closed => {
|
MapEditor::Closed => {
|
||||||
|
let tx_top = "Map Required To Proceed";
|
||||||
|
let tx_bot = "CAS.qterm//CyberAcme Systems Inc.";
|
||||||
|
|
||||||
|
let dw = d.w();
|
||||||
|
let dh = d.h();
|
||||||
|
let iw = im.w();
|
||||||
|
let ih = im.h();
|
||||||
|
|
||||||
d.clear(Color16::new(0, 0, 0));
|
d.clear(Color16::new(0, 0, 0));
|
||||||
|
|
||||||
d.image((d.w() / 2 - im.w() / 2, d.h() / 2 - im.h() / 2), im);
|
d.image((dw / 2 - iw / 2, dh / 2 - ih / 2), im);
|
||||||
|
|
||||||
let text = "Map Required To Proceed";
|
d.rect(Rect{x: 0, y: 0, w: dw, h: 18}, CR_DARK_RED);
|
||||||
d.rect(Rect{x: 0, y: 0, w: d.w(), h: 18}, CR_DARK_RED);
|
d.text((4, 14), tx_top, CR_RED);
|
||||||
d.text((4, 14), text, CR_RED);
|
|
||||||
|
|
||||||
let text = "CAS.qterm//CyberAcme Systems Inc.";
|
d.rect(Rect{x: 0, y: dh - 18, w: dw, h: 18}, CR_DARK_RED);
|
||||||
d.rect(Rect{x: 0, y: d.h() - 18, w: d.w(), h: 18}, CR_DARK_RED);
|
d.text((4, dh - 4), tx_bot, CR_RED);
|
||||||
d.text((4, d.h() - 4), text, CR_RED);
|
|
||||||
}
|
}
|
||||||
MapEditor::Opened(_st) => {
|
MapEditor::Opened(_st) => {
|
||||||
d.clear(Color16::new(0, 0, 0));
|
d.clear(Color16::new(0, 0, 0));
|
||||||
|
@ -50,6 +56,7 @@ impl MapEditor
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns `true` if `self` is closed.
|
/// Returns `true` if `self` is closed.
|
||||||
|
#[allow(dead_code)]
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn is_closed(&self) -> bool
|
pub fn is_closed(&self) -> bool
|
||||||
{
|
{
|
||||||
|
@ -60,6 +67,7 @@ impl MapEditor
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns `true` if `self` is opened.
|
/// Returns `true` if `self` is opened.
|
||||||
|
#[allow(dead_code)]
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn is_opened(&self) -> bool
|
pub fn is_opened(&self) -> bool
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,8 +1,7 @@
|
||||||
mod editor;
|
mod editor;
|
||||||
mod interfaces;
|
mod interfaces;
|
||||||
|
|
||||||
use crate::{editor::MapEditor,
|
use crate::interfaces::*;
|
||||||
interfaces::*};
|
|
||||||
use gdk_pixbuf_sys::*;
|
use gdk_pixbuf_sys::*;
|
||||||
use gdk_sys::*;
|
use gdk_sys::*;
|
||||||
use gio_sys::*;
|
use gio_sys::*;
|
||||||
|
@ -10,14 +9,14 @@ use glib_sys::*;
|
||||||
use gobject_sys::*;
|
use gobject_sys::*;
|
||||||
use gtk_sys::*;
|
use gtk_sys::*;
|
||||||
use maraiah::{c_str, durandal::ffi};
|
use maraiah::{c_str, durandal::ffi};
|
||||||
use std::rc::Rc;
|
use std::{cell::RefCell, rc::Rc};
|
||||||
|
|
||||||
/// Called whne the application activates in order to set everything up.
|
/// Called whne the application activates in order to set everything up.
|
||||||
unsafe extern "C" fn app_activate(app: *mut GtkApplication, edit: gpointer)
|
unsafe extern "C" fn app_activate(app: *mut GtkApplication, edit: gpointer)
|
||||||
{
|
{
|
||||||
// this ref will be cloned around a bit, but will ultimately be dropped at
|
// this ref will be cloned around a bit, but will ultimately be dropped at
|
||||||
// the end of this function.
|
// the end of this function.
|
||||||
let edit = Rc::from_raw(edit as *mut MapEditor);
|
let edit = Rc::from_raw(edit as *const MapEditorRef);
|
||||||
|
|
||||||
setup_css();
|
setup_css();
|
||||||
|
|
||||||
|
@ -35,14 +34,14 @@ unsafe extern "C" fn app_activate(app: *mut GtkApplication, edit: gpointer)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Sets up the map view window's drawing area.
|
/// Sets up the map view window's drawing area.
|
||||||
unsafe fn setup_draw_area(b: *mut GtkBuilder, edit: Rc<MapEditor>)
|
unsafe fn setup_draw_area(b: *mut GtkBuilder, edit: Rc<MapEditorRef>)
|
||||||
{
|
{
|
||||||
struct RenderState
|
struct RenderState
|
||||||
{
|
{
|
||||||
im_nomap: *mut GdkPixbuf,
|
im_nomap: *mut GdkPixbuf,
|
||||||
ax: *mut GtkAdjustment,
|
ax: *mut GtkAdjustment,
|
||||||
ay: *mut GtkAdjustment,
|
ay: *mut GtkAdjustment,
|
||||||
edit: Rc<MapEditor>,
|
edit: Rc<MapEditorRef>,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Callback to finalize the drawing area.
|
/// Callback to finalize the drawing area.
|
||||||
|
@ -78,13 +77,18 @@ unsafe fn setup_draw_area(b: *mut GtkBuilder, edit: Rc<MapEditor>)
|
||||||
let im = CrImage(rend.im_nomap);
|
let im = CrImage(rend.im_nomap);
|
||||||
let dr = CrDrawArea::new(ctx, w, h);
|
let dr = CrDrawArea::new(ctx, w, h);
|
||||||
|
|
||||||
rend.edit.draw(&dr, &im);
|
rend.edit.borrow().draw(&dr, &im);
|
||||||
|
|
||||||
1
|
1
|
||||||
}
|
}
|
||||||
|
|
||||||
let wid: *mut GtkDrawingArea = get_obj(b, c_str!("draw-area"));
|
let wid: *mut GtkDrawingArea = get_obj(b, c_str!("draw-area"));
|
||||||
|
|
||||||
|
{
|
||||||
|
let mut edit = edit.borrow_mut();
|
||||||
|
edit.call.push(Box::new(move || gtk_widget_queue_draw(wid as _)));
|
||||||
|
}
|
||||||
|
|
||||||
let ax: *mut GtkAdjustment = get_obj(b, c_str!("adj-map-horz"));
|
let ax: *mut GtkAdjustment = get_obj(b, c_str!("adj-map-horz"));
|
||||||
let ay: *mut GtkAdjustment = get_obj(b, c_str!("adj-map-vert"));
|
let ay: *mut GtkAdjustment = get_obj(b, c_str!("adj-map-vert"));
|
||||||
|
|
||||||
|
@ -214,7 +218,7 @@ unsafe fn setup_explicit_drop(b: *mut GtkBuilder, win: *mut GtkWindow)
|
||||||
/// Sets up the main menu window.
|
/// Sets up the main menu window.
|
||||||
unsafe fn setup_win_main(b: *mut GtkBuilder,
|
unsafe fn setup_win_main(b: *mut GtkBuilder,
|
||||||
app: *mut GtkApplication,
|
app: *mut GtkApplication,
|
||||||
edit: Rc<MapEditor>)
|
edit: Rc<MapEditorRef>)
|
||||||
{
|
{
|
||||||
/// Callback to close the window when the "Quit" button is pressed.
|
/// Callback to close the window when the "Quit" button is pressed.
|
||||||
unsafe extern "C" fn c_quit_act(_: *mut GtkWidget, win: gpointer)
|
unsafe extern "C" fn c_quit_act(_: *mut GtkWidget, win: gpointer)
|
||||||
|
@ -225,8 +229,9 @@ unsafe fn setup_win_main(b: *mut GtkBuilder,
|
||||||
/// Callback to create a new editor state when the "New" button is pressed.
|
/// Callback to create a new editor state when the "New" button is pressed.
|
||||||
unsafe extern "C" fn c_new_act(_: *mut GtkWidget, edit: gpointer)
|
unsafe extern "C" fn c_new_act(_: *mut GtkWidget, edit: gpointer)
|
||||||
{
|
{
|
||||||
let edit = edit as *mut MapEditor;
|
let edit = edit as *const MapEditorRef;
|
||||||
let edit = &mut *edit;
|
let edit = &*edit;
|
||||||
|
let mut edit = edit.borrow_mut();
|
||||||
|
|
||||||
if edit.is_opened() {
|
if edit.is_opened() {
|
||||||
let titl = c_str!("Confirm");
|
let titl = c_str!("Confirm");
|
||||||
|
@ -238,12 +243,14 @@ unsafe fn setup_win_main(b: *mut GtkBuilder,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
*edit = MapEditor::new_opened();
|
edit.open_new();
|
||||||
|
edit.cause_update();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Callback to finalize the editor state reference.
|
/// Callback to finalize the editor state reference.
|
||||||
unsafe extern "C" fn c_new_done(_: *mut GtkWidget, edit: gpointer)
|
unsafe extern "C" fn c_new_done(_: *mut GtkWidget, edit: gpointer)
|
||||||
{
|
{
|
||||||
|
let edit = edit as *const MapEditorRef;
|
||||||
Rc::from_raw(edit);
|
Rc::from_raw(edit);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -376,7 +383,10 @@ fn main()
|
||||||
g_static_resource_init(&mut resource);
|
g_static_resource_init(&mut resource);
|
||||||
|
|
||||||
// create a container for the editor state
|
// create a container for the editor state
|
||||||
let edit = Rc::new(MapEditor::new_closed());
|
let edit = MapEditor{edit: editor::MapEditor::new_closed(),
|
||||||
|
call: Vec::new(),
|
||||||
|
done: Vec::new()};
|
||||||
|
let edit = Rc::new(RefCell::new(edit));
|
||||||
let eptr = Rc::into_raw(edit.clone());
|
let eptr = Rc::into_raw(edit.clone());
|
||||||
|
|
||||||
// create and run the app
|
// create and run the app
|
||||||
|
@ -398,4 +408,35 @@ fn main()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl MapEditor
|
||||||
|
{
|
||||||
|
fn cause_update(&mut self) {for cb in &mut self.call {cb();}}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Drop for MapEditor
|
||||||
|
{
|
||||||
|
fn drop(&mut self) {for cb in &mut self.done {cb();}}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl std::ops::Deref for MapEditor
|
||||||
|
{
|
||||||
|
type Target = editor::MapEditor;
|
||||||
|
|
||||||
|
fn deref(&self) -> &editor::MapEditor {&self.edit}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl std::ops::DerefMut for MapEditor
|
||||||
|
{
|
||||||
|
fn deref_mut(&mut self) -> &mut editor::MapEditor {&mut self.edit}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct MapEditor
|
||||||
|
{
|
||||||
|
edit: editor::MapEditor,
|
||||||
|
call: Vec<Box<dyn FnMut()>>,
|
||||||
|
done: Vec<Box<dyn FnMut()>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
type MapEditorRef = RefCell<MapEditor>;
|
||||||
|
|
||||||
// EOF
|
// EOF
|
||||||
|
|
Loading…
Reference in New Issue