Compare commits

...

4 Commits

Author SHA1 Message Date
an d56b3db1fe move editor to rozinante 2019-03-27 14:07:33 -04:00
an b427f4c99d use new module spec 2019-03-27 14:07:10 -04:00
an 8693f7605a extra comments 2019-03-27 07:56:30 -04:00
an 742f0c1c8e fix mutability of DrawArea 2019-03-27 07:56:06 -04:00
11 changed files with 126 additions and 68 deletions

View File

@ -50,6 +50,11 @@ impl CStringVec
}
}
impl Default for CStringVec
{
fn default() -> Self {Self::new()}
}
/// An owned null-terminated string vector.
#[derive(Debug)]
pub struct CStringVec

View File

@ -2,5 +2,6 @@
pub mod color;
pub mod draw;
pub mod editor;
// EOF

View File

@ -2,7 +2,7 @@
use crate::durandal::image::Color16;
pub const CR_RED: Color16 = Color16::new(0xFFFF, 0, 0);
pub const CR_DARK_RED: Color16 = Color16::new(0x4700, 0, 0);
pub const RED: Color16 = Color16::new(0xFFFF, 0, 0);
pub const DARK_RED: Color16 = Color16::new(0x4700, 0, 0);
// EOF

View File

@ -25,22 +25,22 @@ pub trait DrawArea
fn h(&self) -> Coord;
/// Fills the entire screen with `cr`. Will also default all settings.
fn clear(&self, cr: impl Color);
fn clear(&mut self, cr: impl Color);
/// Changes the width for lines. The default is `1`.
fn line_width(&self, width: u8);
fn line_width(&mut self, width: u8);
/// Draws a line from `p1` to `p2` with color `cr`.
fn line(&self, p1: Point, p2: Point, cr: impl Color);
fn line(&mut self, p1: Point, p2: Point, cr: impl Color);
/// Draws a rectangle `rect` of color `cr`.
fn rect(&self, rect: Rect, cr: impl Color);
fn rect(&mut self, rect: Rect, cr: impl Color);
/// Draws the Unicode `text` at `pos` stroked with color `cr`.
fn text(&self, pos: Point, text: &str, cr: impl Color);
fn text(&mut self, pos: Point, text: &str, cr: impl Color);
/// Draws `im` at `pos`, starting from the top left column.
fn image(&self, pos: Point, im: &Self::NativeImage);
fn image(&mut self, pos: Point, im: &Self::NativeImage);
}
/// A type capable of representing any coordinate on any axis.

View File

@ -4,9 +4,11 @@
//! state and human interactions with it, but is otherwise not permitted to
//! directly edit it.
use maraiah::{durandal::image::*,
marathon::map,
rozinante::{color::*, draw::*}};
pub mod block;
pub mod state;
use crate::durandal::image::*;
use super::{color, draw::*};
impl MapEditor
{
@ -21,42 +23,42 @@ impl MapEditor
#[inline]
pub fn open_new(&mut self)
{
*self = MapEditor::Opened(MapEditorState::default());
*self = MapEditor::Opened(state::State::default());
}
/// Draws the screen for this editor state.
pub fn draw<D, I>(&self, d: &D, im: &I)
pub fn draw<D, I>(&self, d: &mut D, im: &I)
where D: DrawArea<NativeImage = I>,
I: CacheImage
{
let dw = d.w();
let dh = d.h();
let iw = im.w();
let ih = im.h();
match self {
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.image((dw / 2 - iw / 2, dh / 2 - ih / 2), im);
d.rect(Rect{x: 0, y: 0, w: dw, h: 18}, CR_DARK_RED);
d.text((4, 14), tx_top, CR_RED);
d.rect(Rect{x: 0, y: 0, w: dw, h: 18}, color::DARK_RED);
d.text((4, 14), tx_top, color::RED);
d.rect(Rect{x: 0, y: dh - 18, w: dw, h: 18}, CR_DARK_RED);
d.text((4, dh - 4), tx_bot, CR_RED);
d.rect(Rect{x: 0, y: dh - 18, w: dw, h: 18}, color::DARK_RED);
d.text((4, dh - 4), tx_bot, color::RED);
}
MapEditor::Opened(_st) => {
MapEditor::Opened(st) => {
d.clear(Color16::new(0, 0, 0));
d.text((dw/2, dh/2), &format!("tool: {:?}", st.tool), color::RED);
}
}
}
/// Returns `true` if `self` is closed.
#[allow(dead_code)]
#[inline]
pub fn is_closed(&self) -> bool
{
@ -67,7 +69,6 @@ impl MapEditor
}
/// Returns `true` if `self` is opened.
#[allow(dead_code)]
#[inline]
pub fn is_opened(&self) -> bool
{
@ -78,39 +79,17 @@ impl MapEditor
}
}
impl Default for Tool
impl Default for MapEditor
{
fn default() -> Tool {Tool::Points}
}
/// Copyable map state.
#[derive(Clone, Default)]
pub struct MapEditorStateBlock
{
info: map::Minf,
}
/// The state of an opened map editor.
#[derive(Default)]
pub struct MapEditorState
{
edit_stack: Vec<MapEditorStateBlock>,
tool: Tool,
#[inline]
fn default() -> Self {Self::new_closed()}
}
/// An entire map editor, which may be opened or closed.
pub enum MapEditor
{
Closed,
Opened(MapEditorState),
}
/// A tool in the map editor.
pub enum Tool
{
Points,
Lines,
Polygons,
Opened(state::State),
}
// EOF

View File

@ -0,0 +1,19 @@
use crate::marathon::map;
impl Default for Block
{
#[inline]
fn default() -> Self
{
Self{info: map::Minf::default()}
}
}
/// Copyable map state.
#[derive(Clone)]
pub struct Block
{
info: map::Minf,
}
// EOF

View File

@ -0,0 +1,48 @@
use super::block;
impl State
{
fn cur_block(&self) -> &block::Block
{
self.blocks.last().unwrap()
}
fn cur_block_mut(&mut self) -> &mut block::Block
{
self.blocks.last_mut().unwrap()
}
}
impl Default for State
{
#[inline]
fn default() -> Self
{
Self{blocks: vec![block::Block::default()],
tool: Tool::default()}
}
}
impl Default for Tool
{
#[inline]
fn default() -> Self {Tool::Points}
}
/// The state of an opened map editor.
pub struct State
{
pub(super) blocks: Vec<block::Block>,
pub(super) tool: Tool,
}
/// A tool in the map editor.
#[derive(Debug)]
pub(super) enum Tool
{
Points,
Lines,
Polygons,
}
// EOF

View File

@ -34,7 +34,7 @@ impl DrawArea for CrDrawArea
fn w(&self) -> Coord {self.w}
fn h(&self) -> Coord {self.h}
fn clear(&self, cr: impl Color)
fn clear(&mut self, cr: impl Color)
{
self.rect(Rect{x: 0, y: 0, w: self.w(), h: self.h()}, cr);
@ -48,7 +48,7 @@ impl DrawArea for CrDrawArea
}
}
fn line_width(&self, width: u8)
fn line_width(&mut self, width: u8)
{
let width = f64::from(width);
@ -57,7 +57,7 @@ impl DrawArea for CrDrawArea
}
}
fn line(&self, p1: Point, p2: Point, cr: impl Color)
fn line(&mut self, p1: Point, p2: Point, cr: impl Color)
{
let (r, g, b) = flt_color(cr);
@ -75,7 +75,7 @@ impl DrawArea for CrDrawArea
}
}
fn rect(&self, rect: Rect, cr: impl Color)
fn rect(&mut self, rect: Rect, cr: impl Color)
{
let px = f64::from(rect.x);
let py = f64::from(rect.y);
@ -91,7 +91,7 @@ impl DrawArea for CrDrawArea
}
}
fn text(&self, pos: Point, text: &str, cr: impl Color)
fn text(&mut self, pos: Point, text: &str, cr: impl Color)
{
let (r, g, b) = flt_color(cr);
@ -107,7 +107,7 @@ impl DrawArea for CrDrawArea
}
}
fn image(&self, pos: Point, im: &Self::NativeImage)
fn image(&mut self, pos: Point, im: &Self::NativeImage)
{
let x = f64::from(pos.0);
let y = f64::from(pos.1);

View File

@ -1,4 +1,3 @@
mod editor;
mod interfaces;
use crate::interfaces::*;
@ -8,10 +7,10 @@ use gio_sys::*;
use glib_sys::*;
use gobject_sys::*;
use gtk_sys::*;
use maraiah::{c_str, durandal::ffi};
use maraiah::{c_str, durandal::ffi, rozinante::editor};
use std::{cell::RefCell, rc::Rc};
/// Called whne the application activates in order to set everything up.
/// Called when the application activates in order to set everything up.
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
@ -36,6 +35,7 @@ unsafe extern "C" fn app_activate(app: *mut GtkApplication, edit: gpointer)
/// Sets up the map view window's drawing area.
unsafe fn setup_draw_area(b: *mut GtkBuilder, edit: Rc<MapEditorRef>)
{
/// All of the state necessary for the drawing area.
struct RenderState
{
im_nomap: *mut GdkPixbuf,
@ -75,20 +75,21 @@ unsafe fn setup_draw_area(b: *mut GtkBuilder, edit: Rc<MapEditorRef>)
gtk_adjustment_set_upper(rend.ay, h);
let im = CrImage(rend.im_nomap);
let dr = CrDrawArea::new(ctx, w, h);
let mut dr = CrDrawArea::new(ctx, w, h);
rend.edit.borrow().draw(&dr, &im);
rend.edit.borrow().draw(&mut dr, &im);
1
}
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 _)));
}
// add a callback to draw the area when updated
edit.borrow_mut().call.push(Box::new(move || {
gtk_widget_queue_draw(wid as _);
}));
// get all of the necessary state and related objects
let ax: *mut GtkAdjustment = get_obj(b, c_str!("adj-map-horz"));
let ay: *mut GtkAdjustment = get_obj(b, c_str!("adj-map-vert"));
@ -226,7 +227,7 @@ unsafe fn setup_win_main(b: *mut GtkBuilder,
gtk_window_close(win as _);
}
/// Callback to create a new editor state when the "New" button is pressed.
/// Callback to create a new map when the "New" button is pressed.
unsafe extern "C" fn c_new_act(_: *mut GtkWidget, edit: gpointer)
{
let edit = edit as *const MapEditorRef;
@ -386,7 +387,8 @@ fn main()
let edit = MapEditor{edit: editor::MapEditor::new_closed(),
call: Vec::new(),
done: Vec::new()};
let edit = Rc::new(RefCell::new(edit));
let edit = RefCell::new(edit);
let edit = Rc::new(edit);
let eptr = Rc::into_raw(edit.clone());
// create and run the app
@ -410,11 +412,13 @@ fn main()
impl MapEditor
{
/// Causes all update callbacks to be called.
fn cause_update(&mut self) {for cb in &mut self.call {cb();}}
}
impl Drop for MapEditor
{
/// Calls all finalization callbacks on drop.
fn drop(&mut self) {for cb in &mut self.done {cb();}}
}
@ -430,6 +434,7 @@ impl std::ops::DerefMut for MapEditor
fn deref_mut(&mut self) -> &mut editor::MapEditor {&mut self.edit}
}
/// Specialized map editor which has callbacks for frontend purposes.
struct MapEditor
{
edit: editor::MapEditor,
@ -437,6 +442,7 @@ struct MapEditor
done: Vec<Box<dyn FnMut()>>,
}
/// A runtime reference to the map editor.
type MapEditorRef = RefCell<MapEditor>;
// EOF