file dance

gui-branch
an 2019-03-24 20:04:49 -04:00
parent faf1f5ee5d
commit 8ccfdd79ef
5 changed files with 112 additions and 47 deletions

View File

@ -24,9 +24,15 @@ pub trait DrawArea
/// The height of the entire area.
fn h(&self) -> Coord;
/// Fills the entire screen with `cr`.
/// Fills the entire screen with `cr`. Will also default all settings.
fn clear(&self, cr: impl Color);
/// Changes the width for lines. The default is `1`.
fn line_width(&self, width: u8);
/// Draws a line from `p1` to `p2` with color `cr`.
fn line(&self, p1: Point, p2: Point, cr: impl Color);
/// Draws a rectangle `rect` of color `cr`.
fn rect(&self, rect: Rect, cr: impl Color);

51
source/tycho/editor.rs Normal file
View File

@ -0,0 +1,51 @@
//! Main map editor module.
//!
//! The entry point is responsible for maintaining the lifetime of the editor
//! state and human interactions with it, but is otherwise not permitted to
//! directly edit it.
use maraiah::{durandal::image::*,
marathon::map,
rozinante::{color::*, draw::*}};
impl MapEditorState
{
/// Creates a new empty map.
pub fn new() -> MapEditorState
{
let info = Default::default();
let ed = MapEditorState{info};
ed
}
/// Draws the "no map" screen.
pub fn draw_none<D, I>(d: &D, im: &I)
where D: DrawArea<NativeImage = I>,
I: CacheImage
{
d.clear(Color16::new(0, 0, 0));
d.image((d.w() / 2 - im.w() / 2, d.h() / 2 - im.h() / 2), im);
d.rect(Rect{x: 0, y: 0, w: d.w(), h: 18}, CR_DARK_RED);
d.text((4, 14), "Map Required To Proceed", CR_RED);
d.rect(Rect{x: 0, y: d.h() - 18, w: d.w(), h: 18}, CR_DARK_RED);
d.text((4, d.h() - 4), "CAS.qterm//CyberAcme Systems Inc.", CR_RED);
}
}
impl Drop for MapEditorState
{
fn drop(&mut self) {eprintln!("dropping MapEditorState");}
}
/// The state of a single opened map.
pub struct MapEditorState
{
info: map::Minf,
}
// EOF

View File

@ -1,39 +0,0 @@
use maraiah::{durandal::image::*,
marathon::*,
rozinante::{color::*, draw::*}};
pub fn draw_map_none<D, I>(d: &D, im: &I)
where D: DrawArea<NativeImage = I>,
I: CacheImage
{
d.clear(Color16::new(0, 0, 0));
d.image((d.w() / 2 - im.w() / 2, d.h() / 2 - im.h() / 2), im);
d.rect(Rect{x: 0, y: 0, w: d.w(), h: 18}, CR_DARK_RED);
d.text((4, 14), "Map Required To Proceed", CR_RED);
d.rect(Rect{x: 0, y: d.h() - 18, w: d.w(), h: 18}, CR_DARK_RED);
d.text((4, d.h() - 4), "CAS.qterm//CyberAcme Systems Inc.", CR_RED);
}
pub fn new_map() -> MapEditorState
{
let info = Default::default();
let ed = MapEditorState{info};
ed
}
impl Drop for MapEditorState
{
fn drop(&mut self) {eprintln!("dropping MapEditorState");}
}
pub struct MapEditorState
{
info: map::Minf,
}
// EOF

View File

@ -1,8 +1,11 @@
//! Implemented interfaces for Rozinante.
use cairo_sys::*;
use gdk_pixbuf_sys::*;
use gdk_sys::*;
use maraiah::{c_str, durandal::{ffi::*, image::*}, rozinante::draw::*};
/// Converts a `Color` to a `f64` triple.
fn flt_color(cr: impl Color) -> (f64, f64, f64)
{
fn flt_color(n: u16) -> f64 {f64::from(n) / f64::from(u16::max_value())}
@ -41,6 +44,34 @@ impl DrawArea for CrDrawArea
unsafe {
cairo_select_font_face(self.ctx, c_str!("Monospace"), sl, wt);
cairo_set_font_size(self.ctx, 14.0);
cairo_set_line_width(self.ctx, 1.0);
}
}
fn line_width(&self, width: u8)
{
let width = f64::from(width);
unsafe {
cairo_set_line_width(self.ctx, width);
}
}
fn line(&self, p1: Point, p2: Point, cr: impl Color)
{
let (r, g, b) = flt_color(cr);
let x1 = f64::from(p1.0);
let y1 = f64::from(p1.1);
let x2 = f64::from(p2.0);
let y2 = f64::from(p2.1);
unsafe {
cairo_set_source_rgb(self.ctx, r, g, b);
cairo_move_to(self.ctx, x1, y1);
cairo_line_to(self.ctx, x2, y2);
cairo_stroke(self.ctx);
}
}
@ -88,8 +119,10 @@ impl DrawArea for CrDrawArea
}
}
/// An image for a `CrDrawArea`.
pub struct CrImage(pub *const GdkPixbuf);
/// A `DrawArea` for a Cairo surface.
pub struct CrDrawArea
{
ctx: *mut cairo_t,

View File

@ -1,8 +1,8 @@
mod hiddenprotocol;
mod noroom;
mod editor;
mod interfaces;
use crate::{hiddenprotocol::*, noroom::*};
use cairo_sys::*;
use crate::{editor::MapEditorState,
interfaces::*};
use gdk_pixbuf_sys::*;
use gdk_sys::*;
use gio_sys::*;
@ -11,6 +11,7 @@ use gobject_sys::*;
use gtk_sys::*;
use maraiah::{c_str, durandal::ffi};
/// Called whne the application activates in order to set everything up.
unsafe extern "C" fn app_activate(app: *mut GtkApplication, dat: gpointer)
{
let dat = dat as *mut Option<MapEditorState>;
@ -32,6 +33,7 @@ unsafe extern "C" fn app_activate(app: *mut GtkApplication, dat: gpointer)
g_object_unref(b as _);
}
/// Sets up the map view window's drawing area.
unsafe fn setup_draw_area(b: *mut GtkBuilder)
{
struct RenderState
@ -45,7 +47,6 @@ unsafe fn setup_draw_area(b: *mut GtkBuilder)
{
let dat = Box::from_raw(dat as *mut RenderState);
// unref everything
g_object_unref(dat.im_nomap as _);
g_object_unref(dat.ax as _);
g_object_unref(dat.ay as _);
@ -54,7 +55,7 @@ unsafe fn setup_draw_area(b: *mut GtkBuilder)
}
unsafe extern "C" fn c_draw(wid: *mut GtkWidget,
ctx: *mut cairo_t,
ctx: *mut cairo_sys::cairo_t,
dat: gpointer)
-> gboolean
{
@ -73,7 +74,7 @@ unsafe fn setup_draw_area(b: *mut GtkBuilder)
let im = CrImage(dat.im_nomap);
let dr = CrDrawArea::new(ctx, w, h);
draw_map_none(&dr, &im);
MapEditorState::draw_none(&dr, &im);
1
}
@ -95,6 +96,7 @@ unsafe fn setup_draw_area(b: *mut GtkBuilder)
connect(wid as _, c_str!("draw"), c_draw as _, dat as _);
}
/// Sets up the map view window.
unsafe fn setup_win_map_view(b: *mut GtkBuilder)
{
let win: *mut GtkWindow = get_obj(b, c_str!("win-map-view"));
@ -104,6 +106,7 @@ unsafe fn setup_win_map_view(b: *mut GtkBuilder)
connect_show(btn as _, win as _);
}
/// Sets up the map tools window.
unsafe fn setup_win_map_tools(b: *mut GtkBuilder)
{
let win: *mut GtkWindow = get_obj(b, c_str!("win-map-tools"));
@ -113,6 +116,7 @@ unsafe fn setup_win_map_tools(b: *mut GtkBuilder)
connect_show(btn as _, win as _);
}
/// Sets up the map properties window.
unsafe fn setup_win_map_prop(b: *mut GtkBuilder)
{
let win: *mut GtkWindow = get_obj(b, c_str!("win-map-prop"));
@ -122,8 +126,11 @@ unsafe fn setup_win_map_prop(b: *mut GtkBuilder)
connect_show(btn as _, win as _);
}
/// Sets up the about dialogue.
unsafe fn setup_about_dlg(b: *mut GtkBuilder)
{
/// Callback to show the dialogue when the "About" button is pressed, and
/// hide it when the "Close" button is pressed on it.
unsafe extern "C" fn c_show(_: *mut GtkWidget, dlg: gpointer)
{
gtk_dialog_run(dlg as _);
@ -148,8 +155,10 @@ unsafe fn setup_about_dlg(b: *mut GtkBuilder)
g_object_unref(img as _);
}
/// Sets up the main menu window.
unsafe fn setup_win_main(b: *mut GtkBuilder, app: *mut GtkApplication)
{
/// Callback to close the window when the "Quit" button is pressed.
unsafe extern "C" fn c_quit(_: *mut GtkWidget, win: gpointer)
{
gtk_window_close(win as _);
@ -164,6 +173,7 @@ unsafe fn setup_win_main(b: *mut GtkBuilder, app: *mut GtkApplication)
connect(btn as _, c_str!("activate"), c_quit as _, win as _);
}
/// Sets up the CSS styling providers.
unsafe fn setup_css()
{
let path = c_str!("/net/greyserv/maraiah/tycho/css");
@ -177,8 +187,10 @@ unsafe fn setup_css()
g_object_unref(css as _);
}
/// Connects a handler that shows a widget when activated.
unsafe fn connect_hide(wid: *mut GtkWidget)
{
/// Callback to hide a widget.
unsafe extern "C" fn c_hide(wid: *mut GtkWidget,
_: *mut GdkEvent,
_: gpointer)
@ -189,6 +201,7 @@ unsafe fn connect_hide(wid: *mut GtkWidget)
connect(wid as _, c_str!("delete-event"), c_hide as _, ffi::null_mut());
}
/// Connects a handler that shows a widget when activated.
unsafe fn connect_show(btn: *mut GtkWidget, wid: *mut GtkWidget)
{
unsafe extern "C" fn c_show(_: *mut GtkWidget, wid: gpointer)
@ -213,6 +226,7 @@ unsafe fn connect(obj: *mut GObject, name: ffi::NT, cb: gpointer, d: gpointer)
g_signal_connect_data(obj, name, cb, d, None, 0);
}
/// Loads a `Pixbuf` from a resource.
unsafe fn load_img(path: ffi::NT) -> *mut GdkPixbuf
{
gdk_pixbuf_new_from_resource(path, ffi::null_mut())