crap
parent
36307aca0a
commit
56df373dc1
|
@ -1,129 +1,7 @@
|
|||
//! Main map editor module.
|
||||
//!
|
||||
//! The entry point is responsible for maintaining the lifetime of the editor
|
||||
//! and human interactions with it, but is otherwise not permitted to directly
|
||||
//! edit it.
|
||||
//! Map editor handling.
|
||||
|
||||
mod block;
|
||||
|
||||
pub use block::*;
|
||||
|
||||
use super::{color, draw::*};
|
||||
use crate::{durandal::image::*, marathon::{machdr, map}};
|
||||
|
||||
impl MapEditor
|
||||
{
|
||||
/// Opens the editor with a new map.
|
||||
pub fn open_new(&mut self)
|
||||
{
|
||||
*self = Self::default();
|
||||
}
|
||||
|
||||
/// Opens the editor with an existing map.
|
||||
pub fn open_buf(&mut self, b: &[u8])
|
||||
{
|
||||
// TODO: handle errors gracefully
|
||||
let b = &b[machdr::try_mac_header(b)..];
|
||||
let wad = map::read(b).expect("bad map file");
|
||||
|
||||
let ent = wad.entries.iter().nth(0).expect("no entries").1;
|
||||
let info = ent.chunks.iter().find_map(|cnk| {
|
||||
match cnk {
|
||||
map::chnk::Chunk::Minf(info) => Some(info),
|
||||
_ => None,
|
||||
}
|
||||
}).expect("no Minf chunk").clone();
|
||||
|
||||
let block = Block{info};
|
||||
|
||||
dbg!(&block);
|
||||
|
||||
*self = Self{blocks: vec![block],
|
||||
tools: Self::default_tools()};
|
||||
}
|
||||
|
||||
/// Draws the screen for this editor state.
|
||||
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();
|
||||
|
||||
let tx_top = "Map Required To Proceed";
|
||||
let tx_bot = "CAS.qterm//CyberAcme Systems Inc.";
|
||||
|
||||
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}, color::DARK_RED);
|
||||
d.text((4, 0), tx_top, color::RED);
|
||||
|
||||
d.rect(Rect{x: 0, y: dh - 18, w: dw, h: 18}, color::DARK_RED);
|
||||
d.text((4, dh - 16), tx_bot, color::RED);
|
||||
*/
|
||||
|
||||
let _ = im;
|
||||
|
||||
let text = &format!("{:#?}", &self);
|
||||
|
||||
d.clear(Color16::new(0, 0, 0));
|
||||
d.text((0, 0), text, color::RED);
|
||||
}
|
||||
|
||||
// Returns the default tools.
|
||||
const fn default_tools() -> (Tool, Tool) {(Tool::Points, Tool::Lines)}
|
||||
|
||||
/// Returns a reference to the current block.
|
||||
pub fn cur_block(&self) -> &Block {self.blocks.last().unwrap()}
|
||||
|
||||
/// Pushes a new block.
|
||||
pub fn push_block(&mut self, blk: Block) {self.blocks.push(blk);}
|
||||
|
||||
/// Returns the current tool.
|
||||
pub fn tool(&self) -> &Tool {&self.tools.0}
|
||||
|
||||
/// Sets the current tool, and returns the previous one.
|
||||
pub fn set_tool(&mut self, t: Tool) -> &Tool
|
||||
{
|
||||
self.tools.1 = self.tools.0.clone();
|
||||
self.tools.0 = t;
|
||||
|
||||
&self.tools.1
|
||||
}
|
||||
|
||||
/// Returns true if the current map is unclean and needs to be saved.
|
||||
pub fn unclean(&self) -> bool {true}
|
||||
}
|
||||
|
||||
impl Default for MapEditor
|
||||
{
|
||||
#[inline]
|
||||
fn default() -> Self
|
||||
{
|
||||
Self{blocks: vec![Block::default()], tools: Self::default_tools()}
|
||||
}
|
||||
}
|
||||
|
||||
/// The state of an opened map editor.
|
||||
#[derive(Debug)]
|
||||
pub struct MapEditor
|
||||
{
|
||||
blocks: Vec<Block>,
|
||||
tools: (Tool, Tool),
|
||||
}
|
||||
|
||||
/// A tool in the map editor.
|
||||
#[derive(Clone, Debug)]
|
||||
pub enum Tool
|
||||
{
|
||||
Points,
|
||||
Lines,
|
||||
Polygons,
|
||||
}
|
||||
pub mod record;
|
||||
pub mod screen;
|
||||
pub mod session;
|
||||
|
||||
// EOF
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
//! Map editor records, or saved client state.
|
||||
|
||||
use crate::marathon::map;
|
||||
|
||||
impl Default for Block
|
||||
impl Default for Record
|
||||
{
|
||||
#[inline]
|
||||
fn default() -> Self {Self{info: map::minf::Minf::default()}}
|
||||
|
@ -8,7 +10,7 @@ impl Default for Block
|
|||
|
||||
/// Copyable, versioned map state.
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct Block
|
||||
pub struct Record
|
||||
{
|
||||
pub info: map::minf::Minf,
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
//! Map editor screen, or current UI state.
|
||||
|
||||
pub trait Screen
|
||||
{
|
||||
/// Opens the editor with a new map.
|
||||
fn open_new(&mut self);
|
||||
|
||||
/// Opens the editor with a new map.
|
||||
fn open_buf(&mut self, b: &[u8]);
|
||||
}
|
||||
|
||||
// EOF
|
|
@ -0,0 +1,20 @@
|
|||
//! Map editor session, or current client state.
|
||||
|
||||
impl Session
|
||||
{
|
||||
/// Opens the editor with a new map.
|
||||
fn open_new(&mut self)
|
||||
{
|
||||
}
|
||||
|
||||
/// Opens the editor with a new map.
|
||||
fn open_buf(&mut self, b: &[u8])
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
struct Session
|
||||
{
|
||||
}
|
||||
|
||||
// EOF
|
|
@ -12,32 +12,333 @@
|
|||
<property name="step_increment">1</property>
|
||||
<property name="page_increment">10</property>
|
||||
</object>
|
||||
<object class="GtkWindow" id="win-map-view">
|
||||
<object class="GtkAdjustment" id="adj-phys-id">
|
||||
<property name="upper">65535</property>
|
||||
<property name="step_increment">1</property>
|
||||
<property name="page_increment">10</property>
|
||||
</object>
|
||||
<object class="GtkAboutDialog" id="dlg-about">
|
||||
<property name="can_focus">False</property>
|
||||
<property name="title" translatable="yes">Map View</property>
|
||||
<property name="default_width">600</property>
|
||||
<property name="default_height">400</property>
|
||||
<child type="titlebar">
|
||||
<property name="modal">True</property>
|
||||
<property name="type_hint">dialog</property>
|
||||
<property name="program_name">Tycho Map Editor</property>
|
||||
<property name="copyright" translatable="yes">By Alison Sanderson. Public domain.</property>
|
||||
<property name="comments" translatable="yes">greetigs i am tico the of superior ai to durdumbal go shoot my soldiers because its funny or ill put you in space</property>
|
||||
<property name="website_label" translatable="yes">Home Page</property>
|
||||
<property name="license" translatable="yes">To the extent possible under law, I, Alison Sanderson, have waived all
|
||||
copyright and related or neighboring rights to this Document as described by
|
||||
the Creative Commons Zero license as follows:
|
||||
|
||||
Creative Commons Legal Code
|
||||
|
||||
CC0 1.0 Universal
|
||||
|
||||
CREATIVE COMMONS CORPORATION IS NOT A LAW FIRM AND DOES NOT PROVIDE
|
||||
LEGAL SERVICES. DISTRIBUTION OF THIS DOCUMENT DOES NOT CREATE AN
|
||||
ATTORNEY-CLIENT RELATIONSHIP. CREATIVE COMMONS PROVIDES THIS
|
||||
INFORMATION ON AN "AS-IS" BASIS. CREATIVE COMMONS MAKES NO WARRANTIES
|
||||
REGARDING THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS
|
||||
PROVIDED HEREUNDER, AND DISCLAIMS LIABILITY FOR DAMAGES RESULTING FROM
|
||||
THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS PROVIDED
|
||||
HEREUNDER.
|
||||
|
||||
Statement of Purpose
|
||||
|
||||
The laws of most jurisdictions throughout the world automatically confer
|
||||
exclusive Copyright and Related Rights (defined below) upon the creator
|
||||
and subsequent owner(s) (each and all, an "owner") of an original work of
|
||||
authorship and/or a database (each, a "Work").
|
||||
|
||||
Certain owners wish to permanently relinquish those rights to a Work for
|
||||
the purpose of contributing to a commons of creative, cultural and
|
||||
scientific works ("Commons") that the public can reliably and without fear
|
||||
of later claims of infringement build upon, modify, incorporate in other
|
||||
works, reuse and redistribute as freely as possible in any form whatsoever
|
||||
and for any purposes, including without limitation commercial purposes.
|
||||
These owners may contribute to the Commons to promote the ideal of a free
|
||||
culture and the further production of creative, cultural and scientific
|
||||
works, or to gain reputation or greater distribution for their Work in
|
||||
part through the use and efforts of others.
|
||||
|
||||
For these and/or other purposes and motivations, and without any
|
||||
expectation of additional consideration or compensation, the person
|
||||
associating CC0 with a Work (the "Affirmer"), to the extent that he or she
|
||||
is an owner of Copyright and Related Rights in the Work, voluntarily
|
||||
elects to apply CC0 to the Work and publicly distribute the Work under its
|
||||
terms, with knowledge of his or her Copyright and Related Rights in the
|
||||
Work and the meaning and intended legal effect of CC0 on those rights.
|
||||
|
||||
1. Copyright and Related Rights. A Work made available under CC0 may be
|
||||
protected by copyright and related or neighboring rights ("Copyright and
|
||||
Related Rights"). Copyright and Related Rights include, but are not
|
||||
limited to, the following:
|
||||
|
||||
i. the right to reproduce, adapt, distribute, perform, display,
|
||||
communicate, and translate a Work;
|
||||
ii. moral rights retained by the original author(s) and/or performer(s);
|
||||
iii. publicity and privacy rights pertaining to a person's image or
|
||||
likeness depicted in a Work;
|
||||
iv. rights protecting against unfair competition in regards to a Work,
|
||||
subject to the limitations in paragraph 4(a), below;
|
||||
v. rights protecting the extraction, dissemination, use and reuse of data
|
||||
in a Work;
|
||||
vi. database rights (such as those arising under Directive 96/9/EC of the
|
||||
European Parliament and of the Council of 11 March 1996 on the legal
|
||||
protection of databases, and under any national implementation
|
||||
thereof, including any amended or successor version of such
|
||||
directive); and
|
||||
vii. other similar, equivalent or corresponding rights throughout the
|
||||
world based on applicable law or treaty, and any national
|
||||
implementations thereof.
|
||||
|
||||
2. Waiver. To the greatest extent permitted by, but not in contravention
|
||||
of, applicable law, Affirmer hereby overtly, fully, permanently,
|
||||
irrevocably and unconditionally waives, abandons, and surrenders all of
|
||||
Affirmer's Copyright and Related Rights and associated claims and causes
|
||||
of action, whether now known or unknown (including existing as well as
|
||||
future claims and causes of action), in the Work (i) in all territories
|
||||
worldwide, (ii) for the maximum duration provided by applicable law or
|
||||
treaty (including future time extensions), (iii) in any current or future
|
||||
medium and for any number of copies, and (iv) for any purpose whatsoever,
|
||||
including without limitation commercial, advertising or promotional
|
||||
purposes (the "Waiver"). Affirmer makes the Waiver for the benefit of each
|
||||
member of the public at large and to the detriment of Affirmer's heirs and
|
||||
successors, fully intending that such Waiver shall not be subject to
|
||||
revocation, rescission, cancellation, termination, or any other legal or
|
||||
equitable action to disrupt the quiet enjoyment of the Work by the public
|
||||
as contemplated by Affirmer's express Statement of Purpose.
|
||||
|
||||
3. Public License Fallback. Should any part of the Waiver for any reason
|
||||
be judged legally invalid or ineffective under applicable law, then the
|
||||
Waiver shall be preserved to the maximum extent permitted taking into
|
||||
account Affirmer's express Statement of Purpose. In addition, to the
|
||||
extent the Waiver is so judged Affirmer hereby grants to each affected
|
||||
person a royalty-free, non transferable, non sublicensable, non exclusive,
|
||||
irrevocable and unconditional license to exercise Affirmer's Copyright and
|
||||
Related Rights in the Work (i) in all territories worldwide, (ii) for the
|
||||
maximum duration provided by applicable law or treaty (including future
|
||||
time extensions), (iii) in any current or future medium and for any number
|
||||
of copies, and (iv) for any purpose whatsoever, including without
|
||||
limitation commercial, advertising or promotional purposes (the
|
||||
"License"). The License shall be deemed effective as of the date CC0 was
|
||||
applied by Affirmer to the Work. Should any part of the License for any
|
||||
reason be judged legally invalid or ineffective under applicable law, such
|
||||
partial invalidity or ineffectiveness shall not invalidate the remainder
|
||||
of the License, and in such case Affirmer hereby affirms that he or she
|
||||
will not (i) exercise any of his or her remaining Copyright and Related
|
||||
Rights in the Work or (ii) assert any associated claims and causes of
|
||||
action with respect to the Work, in either case contrary to Affirmer's
|
||||
express Statement of Purpose.
|
||||
|
||||
4. Limitations and Disclaimers.
|
||||
|
||||
a. No trademark or patent rights held by Affirmer are waived, abandoned,
|
||||
surrendered, licensed or otherwise affected by this document.
|
||||
b. Affirmer offers the Work as-is and makes no representations or
|
||||
warranties of any kind concerning the Work, express, implied,
|
||||
statutory or otherwise, including without limitation warranties of
|
||||
title, merchantability, fitness for a particular purpose, non
|
||||
infringement, or the absence of latent or other defects, accuracy, or
|
||||
the present or absence of errors, whether or not discoverable, all to
|
||||
the greatest extent permissible under applicable law.
|
||||
c. Affirmer disclaims responsibility for clearing rights of other persons
|
||||
that may apply to the Work or any use thereof, including without
|
||||
limitation any person's Copyright and Related Rights in the Work.
|
||||
Further, Affirmer disclaims responsibility for obtaining any necessary
|
||||
consents, permissions or other rights required for any use of the
|
||||
Work.
|
||||
d. Affirmer understands and acknowledges that Creative Commons is not a
|
||||
party to this document and has no duty or obligation with respect to
|
||||
this CC0 or use of the Work.
|
||||
</property>
|
||||
<property name="logo_icon_name">image-loading</property>
|
||||
<property name="license_type">custom</property>
|
||||
<child>
|
||||
<placeholder/>
|
||||
</child>
|
||||
<child internal-child="vbox">
|
||||
<object class="GtkBox">
|
||||
<property name="can_focus">False</property>
|
||||
<property name="orientation">vertical</property>
|
||||
<property name="spacing">2</property>
|
||||
<child internal-child="action_area">
|
||||
<object class="GtkButtonBox">
|
||||
<property name="can_focus">False</property>
|
||||
<property name="layout_style">end</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">False</property>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<placeholder/>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child internal-child="accessible">
|
||||
<object class="AtkObject" id="dlg-about-atkobject">
|
||||
<property name="AtkObject::accessible-name" translatable="yes">About Screen</property>
|
||||
<property name="AtkObject::accessible-description" translatable="yes">The about screen for Tycho.</property>
|
||||
<property name="AtkObject::accessible-role" translatable="yes">dialog</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
<object class="GtkImage" id="img-lines">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="pixel_size">24</property>
|
||||
<property name="icon_name">tycho-lines</property>
|
||||
</object>
|
||||
<object class="GtkImage" id="img-points">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="pixel_size">24</property>
|
||||
<property name="icon_name">tycho-points</property>
|
||||
</object>
|
||||
<object class="GtkImage" id="img-polys">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="pixel_size">24</property>
|
||||
<property name="icon_name">tycho-polys</property>
|
||||
</object>
|
||||
<object class="GtkWindow" id="win-main">
|
||||
<property name="can_focus">False</property>
|
||||
<property name="title" translatable="yes">Tycho</property>
|
||||
<property name="resizable">False</property>
|
||||
<property name="default_width">120</property>
|
||||
<property name="default_height">250</property>
|
||||
<child>
|
||||
<placeholder/>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkScrolledWindow">
|
||||
<object class="GtkMenuBar">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="hscrollbar_policy">always</property>
|
||||
<property name="vscrollbar_policy">always</property>
|
||||
<property name="window_placement">top-right</property>
|
||||
<property name="overlay_scrolling">False</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="pack_direction">ttb</property>
|
||||
<child>
|
||||
<object class="GtkViewport">
|
||||
<object class="GtkMenuItem">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="hadjustment">adj-map-horz</property>
|
||||
<property name="vadjustment">adj-map-vert</property>
|
||||
<child>
|
||||
<object class="GtkDrawingArea" id="draw-area">
|
||||
<property name="label" translatable="yes">_File</property>
|
||||
<property name="use_underline">True</property>
|
||||
<child type="submenu">
|
||||
<object class="GtkMenu">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<child>
|
||||
<object class="GtkMenuItem" id="btn-new">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="tooltip_text" translatable="yes">Create a new project.</property>
|
||||
<property name="label" translatable="yes">_New Project</property>
|
||||
<property name="use_underline">True</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkMenuItem" id="btn-open">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="tooltip_text" translatable="yes">Opens any type of project file.</property>
|
||||
<property name="label" translatable="yes">_Open</property>
|
||||
<property name="use_underline">True</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkMenuItem" id="btn-save">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="tooltip_text" translatable="yes">Saves the currently open project.</property>
|
||||
<property name="label" translatable="yes">_Save</property>
|
||||
<property name="use_underline">True</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkSeparatorMenuItem">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkMenuItem" id="btn-quit">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="tooltip_text" translatable="yes">Quit the application.</property>
|
||||
<property name="label" translatable="yes">_Quit</property>
|
||||
<property name="use_underline">True</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkMenuItem">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="label" translatable="yes">_View</property>
|
||||
<property name="use_underline">True</property>
|
||||
<child type="submenu">
|
||||
<object class="GtkMenu">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<child>
|
||||
<object class="GtkMenuItem" id="btn-show-map-view">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="tooltip_text" translatable="yes">Opens the map view window.</property>
|
||||
<property name="label" translatable="yes">Show _Map View</property>
|
||||
<property name="use_underline">True</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkMenuItem" id="btn-show-map-tools">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="tooltip_text" translatable="yes">Opens the map toolbox window.</property>
|
||||
<property name="label" translatable="yes">Show Map _Tools</property>
|
||||
<property name="use_underline">True</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkMenuItem" id="btn-show-map-prop">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="label" translatable="yes">Show Map _Properties</property>
|
||||
<property name="use_underline">True</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkSeparatorMenuItem">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkMenuItem">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="right_justified">True</property>
|
||||
<property name="label" translatable="yes">_Info</property>
|
||||
<property name="use_underline">True</property>
|
||||
<child type="submenu">
|
||||
<object class="GtkMenu">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<child>
|
||||
<object class="GtkMenuItem" id="btn-about">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="tooltip_text" translatable="yes">Opens a window with information about this program.</property>
|
||||
<property name="label" translatable="yes">_About</property>
|
||||
<property name="use_underline">True</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
|
@ -45,15 +346,12 @@
|
|||
</object>
|
||||
</child>
|
||||
</object>
|
||||
<object class="GtkAdjustment" id="adj-phys-id">
|
||||
<property name="upper">65535</property>
|
||||
<property name="step_increment">1</property>
|
||||
<property name="page_increment">10</property>
|
||||
</object>
|
||||
<object class="GtkWindow" id="win-map-prop">
|
||||
<property name="can_focus">False</property>
|
||||
<property name="border_width">5</property>
|
||||
<property name="title" translatable="yes">Map Properties</property>
|
||||
<property name="transient_for">win-main</property>
|
||||
<property name="attached_to">win-main</property>
|
||||
<child>
|
||||
<placeholder/>
|
||||
</child>
|
||||
|
@ -898,200 +1196,56 @@
|
|||
<property name="position">3</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
<object class="GtkAboutDialog" id="dlg-about">
|
||||
<property name="can_focus">False</property>
|
||||
<property name="modal">True</property>
|
||||
<property name="type_hint">dialog</property>
|
||||
<property name="program_name">Tycho Map Editor</property>
|
||||
<property name="copyright" translatable="yes">By Alison Sanderson. Public domain.</property>
|
||||
<property name="comments" translatable="yes">greetigs i am tico the of superior ai to durdumbal go shoot my soldiers because its funny or ill put you in space</property>
|
||||
<property name="website_label" translatable="yes">Home Page</property>
|
||||
<property name="license" translatable="yes">To the extent possible under law, I, Alison Sanderson, have waived all
|
||||
copyright and related or neighboring rights to this Document as described by
|
||||
the Creative Commons Zero license as follows:
|
||||
|
||||
Creative Commons Legal Code
|
||||
|
||||
CC0 1.0 Universal
|
||||
|
||||
CREATIVE COMMONS CORPORATION IS NOT A LAW FIRM AND DOES NOT PROVIDE
|
||||
LEGAL SERVICES. DISTRIBUTION OF THIS DOCUMENT DOES NOT CREATE AN
|
||||
ATTORNEY-CLIENT RELATIONSHIP. CREATIVE COMMONS PROVIDES THIS
|
||||
INFORMATION ON AN "AS-IS" BASIS. CREATIVE COMMONS MAKES NO WARRANTIES
|
||||
REGARDING THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS
|
||||
PROVIDED HEREUNDER, AND DISCLAIMS LIABILITY FOR DAMAGES RESULTING FROM
|
||||
THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS PROVIDED
|
||||
HEREUNDER.
|
||||
|
||||
Statement of Purpose
|
||||
|
||||
The laws of most jurisdictions throughout the world automatically confer
|
||||
exclusive Copyright and Related Rights (defined below) upon the creator
|
||||
and subsequent owner(s) (each and all, an "owner") of an original work of
|
||||
authorship and/or a database (each, a "Work").
|
||||
|
||||
Certain owners wish to permanently relinquish those rights to a Work for
|
||||
the purpose of contributing to a commons of creative, cultural and
|
||||
scientific works ("Commons") that the public can reliably and without fear
|
||||
of later claims of infringement build upon, modify, incorporate in other
|
||||
works, reuse and redistribute as freely as possible in any form whatsoever
|
||||
and for any purposes, including without limitation commercial purposes.
|
||||
These owners may contribute to the Commons to promote the ideal of a free
|
||||
culture and the further production of creative, cultural and scientific
|
||||
works, or to gain reputation or greater distribution for their Work in
|
||||
part through the use and efforts of others.
|
||||
|
||||
For these and/or other purposes and motivations, and without any
|
||||
expectation of additional consideration or compensation, the person
|
||||
associating CC0 with a Work (the "Affirmer"), to the extent that he or she
|
||||
is an owner of Copyright and Related Rights in the Work, voluntarily
|
||||
elects to apply CC0 to the Work and publicly distribute the Work under its
|
||||
terms, with knowledge of his or her Copyright and Related Rights in the
|
||||
Work and the meaning and intended legal effect of CC0 on those rights.
|
||||
|
||||
1. Copyright and Related Rights. A Work made available under CC0 may be
|
||||
protected by copyright and related or neighboring rights ("Copyright and
|
||||
Related Rights"). Copyright and Related Rights include, but are not
|
||||
limited to, the following:
|
||||
|
||||
i. the right to reproduce, adapt, distribute, perform, display,
|
||||
communicate, and translate a Work;
|
||||
ii. moral rights retained by the original author(s) and/or performer(s);
|
||||
iii. publicity and privacy rights pertaining to a person's image or
|
||||
likeness depicted in a Work;
|
||||
iv. rights protecting against unfair competition in regards to a Work,
|
||||
subject to the limitations in paragraph 4(a), below;
|
||||
v. rights protecting the extraction, dissemination, use and reuse of data
|
||||
in a Work;
|
||||
vi. database rights (such as those arising under Directive 96/9/EC of the
|
||||
European Parliament and of the Council of 11 March 1996 on the legal
|
||||
protection of databases, and under any national implementation
|
||||
thereof, including any amended or successor version of such
|
||||
directive); and
|
||||
vii. other similar, equivalent or corresponding rights throughout the
|
||||
world based on applicable law or treaty, and any national
|
||||
implementations thereof.
|
||||
|
||||
2. Waiver. To the greatest extent permitted by, but not in contravention
|
||||
of, applicable law, Affirmer hereby overtly, fully, permanently,
|
||||
irrevocably and unconditionally waives, abandons, and surrenders all of
|
||||
Affirmer's Copyright and Related Rights and associated claims and causes
|
||||
of action, whether now known or unknown (including existing as well as
|
||||
future claims and causes of action), in the Work (i) in all territories
|
||||
worldwide, (ii) for the maximum duration provided by applicable law or
|
||||
treaty (including future time extensions), (iii) in any current or future
|
||||
medium and for any number of copies, and (iv) for any purpose whatsoever,
|
||||
including without limitation commercial, advertising or promotional
|
||||
purposes (the "Waiver"). Affirmer makes the Waiver for the benefit of each
|
||||
member of the public at large and to the detriment of Affirmer's heirs and
|
||||
successors, fully intending that such Waiver shall not be subject to
|
||||
revocation, rescission, cancellation, termination, or any other legal or
|
||||
equitable action to disrupt the quiet enjoyment of the Work by the public
|
||||
as contemplated by Affirmer's express Statement of Purpose.
|
||||
|
||||
3. Public License Fallback. Should any part of the Waiver for any reason
|
||||
be judged legally invalid or ineffective under applicable law, then the
|
||||
Waiver shall be preserved to the maximum extent permitted taking into
|
||||
account Affirmer's express Statement of Purpose. In addition, to the
|
||||
extent the Waiver is so judged Affirmer hereby grants to each affected
|
||||
person a royalty-free, non transferable, non sublicensable, non exclusive,
|
||||
irrevocable and unconditional license to exercise Affirmer's Copyright and
|
||||
Related Rights in the Work (i) in all territories worldwide, (ii) for the
|
||||
maximum duration provided by applicable law or treaty (including future
|
||||
time extensions), (iii) in any current or future medium and for any number
|
||||
of copies, and (iv) for any purpose whatsoever, including without
|
||||
limitation commercial, advertising or promotional purposes (the
|
||||
"License"). The License shall be deemed effective as of the date CC0 was
|
||||
applied by Affirmer to the Work. Should any part of the License for any
|
||||
reason be judged legally invalid or ineffective under applicable law, such
|
||||
partial invalidity or ineffectiveness shall not invalidate the remainder
|
||||
of the License, and in such case Affirmer hereby affirms that he or she
|
||||
will not (i) exercise any of his or her remaining Copyright and Related
|
||||
Rights in the Work or (ii) assert any associated claims and causes of
|
||||
action with respect to the Work, in either case contrary to Affirmer's
|
||||
express Statement of Purpose.
|
||||
|
||||
4. Limitations and Disclaimers.
|
||||
|
||||
a. No trademark or patent rights held by Affirmer are waived, abandoned,
|
||||
surrendered, licensed or otherwise affected by this document.
|
||||
b. Affirmer offers the Work as-is and makes no representations or
|
||||
warranties of any kind concerning the Work, express, implied,
|
||||
statutory or otherwise, including without limitation warranties of
|
||||
title, merchantability, fitness for a particular purpose, non
|
||||
infringement, or the absence of latent or other defects, accuracy, or
|
||||
the present or absence of errors, whether or not discoverable, all to
|
||||
the greatest extent permissible under applicable law.
|
||||
c. Affirmer disclaims responsibility for clearing rights of other persons
|
||||
that may apply to the Work or any use thereof, including without
|
||||
limitation any person's Copyright and Related Rights in the Work.
|
||||
Further, Affirmer disclaims responsibility for obtaining any necessary
|
||||
consents, permissions or other rights required for any use of the
|
||||
Work.
|
||||
d. Affirmer understands and acknowledges that Creative Commons is not a
|
||||
party to this document and has no duty or obligation with respect to
|
||||
this CC0 or use of the Work.
|
||||
</property>
|
||||
<property name="logo_icon_name">image-loading</property>
|
||||
<property name="license_type">custom</property>
|
||||
<child>
|
||||
<placeholder/>
|
||||
</child>
|
||||
<child internal-child="vbox">
|
||||
<object class="GtkBox">
|
||||
<property name="can_focus">False</property>
|
||||
<property name="orientation">vertical</property>
|
||||
<property name="spacing">2</property>
|
||||
<child internal-child="action_area">
|
||||
<child>
|
||||
<object class="GtkButtonBox">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="layout_style">end</property>
|
||||
<child>
|
||||
<object class="GtkButton">
|
||||
<property name="label" translatable="yes">_Save</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="receives_default">True</property>
|
||||
<property name="use_underline">True</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">True</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkButton">
|
||||
<property name="label" translatable="yes">_Close</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="receives_default">True</property>
|
||||
<property name="use_underline">True</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">True</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">False</property>
|
||||
<property name="position">0</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">4</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<placeholder/>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child internal-child="accessible">
|
||||
<object class="AtkObject" id="dlg-about-atkobject">
|
||||
<property name="AtkObject::accessible-name" translatable="yes">About Screen</property>
|
||||
<property name="AtkObject::accessible-description" translatable="yes">The about screen for Tycho.</property>
|
||||
<property name="AtkObject::accessible-role" translatable="yes">dialog</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
<object class="GtkImage" id="img-lines">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="pixel_size">24</property>
|
||||
<property name="icon_name">tycho-lines</property>
|
||||
</object>
|
||||
<object class="GtkImage" id="img-points">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="pixel_size">24</property>
|
||||
<property name="icon_name">tycho-points</property>
|
||||
</object>
|
||||
<object class="GtkImage" id="img-polys">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="pixel_size">24</property>
|
||||
<property name="icon_name">tycho-polys</property>
|
||||
</object>
|
||||
<object class="GtkWindow" id="win-map-tools">
|
||||
<property name="can_focus">False</property>
|
||||
<property name="title" translatable="yes">Tool Palette</property>
|
||||
<property name="default_height">250</property>
|
||||
<property name="skip_taskbar_hint">True</property>
|
||||
<property name="transient_for">win-main</property>
|
||||
<property name="attached_to">win-main</property>
|
||||
<child>
|
||||
<placeholder/>
|
||||
</child>
|
||||
|
@ -1186,142 +1340,34 @@ express Statement of Purpose.
|
|||
</object>
|
||||
</child>
|
||||
</object>
|
||||
<object class="GtkWindow" id="win-main">
|
||||
<object class="GtkWindow" id="win-map-view">
|
||||
<property name="can_focus">False</property>
|
||||
<property name="title" translatable="yes">Tycho</property>
|
||||
<property name="resizable">False</property>
|
||||
<property name="default_width">120</property>
|
||||
<property name="default_height">250</property>
|
||||
<child>
|
||||
<property name="title" translatable="yes">Map View</property>
|
||||
<property name="default_width">600</property>
|
||||
<property name="default_height">400</property>
|
||||
<property name="transient_for">win-main</property>
|
||||
<property name="attached_to">win-main</property>
|
||||
<child type="titlebar">
|
||||
<placeholder/>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkMenuBar">
|
||||
<object class="GtkScrolledWindow">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="pack_direction">ttb</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="hscrollbar_policy">always</property>
|
||||
<property name="vscrollbar_policy">always</property>
|
||||
<property name="window_placement">top-right</property>
|
||||
<property name="overlay_scrolling">False</property>
|
||||
<child>
|
||||
<object class="GtkMenuItem">
|
||||
<object class="GtkViewport">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="label" translatable="yes">_File</property>
|
||||
<property name="use_underline">True</property>
|
||||
<child type="submenu">
|
||||
<object class="GtkMenu">
|
||||
<property name="hadjustment">adj-map-horz</property>
|
||||
<property name="vadjustment">adj-map-vert</property>
|
||||
<child>
|
||||
<object class="GtkDrawingArea" id="draw-area">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<child>
|
||||
<object class="GtkMenuItem" id="btn-new">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="tooltip_text" translatable="yes">Create a new project.</property>
|
||||
<property name="label" translatable="yes">_New Project</property>
|
||||
<property name="use_underline">True</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkMenuItem" id="btn-open">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="tooltip_text" translatable="yes">Opens any type of project file.</property>
|
||||
<property name="label" translatable="yes">_Open</property>
|
||||
<property name="use_underline">True</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkMenuItem" id="btn-save">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="tooltip_text" translatable="yes">Saves the currently open project.</property>
|
||||
<property name="label" translatable="yes">_Save</property>
|
||||
<property name="use_underline">True</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkSeparatorMenuItem">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkMenuItem" id="btn-quit">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="tooltip_text" translatable="yes">Quit the application.</property>
|
||||
<property name="label" translatable="yes">_Quit</property>
|
||||
<property name="use_underline">True</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkMenuItem">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="label" translatable="yes">_View</property>
|
||||
<property name="use_underline">True</property>
|
||||
<child type="submenu">
|
||||
<object class="GtkMenu">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<child>
|
||||
<object class="GtkMenuItem" id="btn-show-map-view">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="tooltip_text" translatable="yes">Opens the map view window.</property>
|
||||
<property name="label" translatable="yes">Show _Map View</property>
|
||||
<property name="use_underline">True</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkMenuItem" id="btn-show-map-tools">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="tooltip_text" translatable="yes">Opens the map toolbox window.</property>
|
||||
<property name="label" translatable="yes">Show Map _Tools</property>
|
||||
<property name="use_underline">True</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkMenuItem" id="btn-show-map-prop">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="label" translatable="yes">Show Map _Properties</property>
|
||||
<property name="use_underline">True</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkSeparatorMenuItem">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkMenuItem">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="right_justified">True</property>
|
||||
<property name="label" translatable="yes">_Info</property>
|
||||
<property name="use_underline">True</property>
|
||||
<child type="submenu">
|
||||
<object class="GtkMenu">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<child>
|
||||
<object class="GtkMenuItem" id="btn-about">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="tooltip_text" translatable="yes">Opens a window with information about this program.</property>
|
||||
<property name="label" translatable="yes">_About</property>
|
||||
<property name="use_underline">True</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
|
|
|
@ -3,151 +3,47 @@
|
|||
use super::glib::*;
|
||||
use gobject_sys::*;
|
||||
use gtk_sys::*;
|
||||
use maraiah::{durandal::ffi, marathon::map, rozinante::editor};
|
||||
use maraiah::{durandal::ffi, marathon::map};
|
||||
use std::cell::RefCell;
|
||||
|
||||
// Iterates over each flag widget with its respective ordered flag object.
|
||||
fn each_flag<T, F>(buttons: &[PropFlag], ordering: &[T], mut f: F)
|
||||
where F: FnMut(&PropFlag, &T)
|
||||
impl EditorModel
|
||||
{
|
||||
for (flg, ord) in buttons.iter().zip(ordering) {
|
||||
f(flg, ord);
|
||||
}
|
||||
}
|
||||
|
||||
// Creates a closure which sets if a button is toggled.
|
||||
fn r_flg<T, F>(mut f: F) -> impl FnMut(&PropFlag, &T)
|
||||
where F: FnMut(&T) -> bool
|
||||
{
|
||||
move |flg, ord| {
|
||||
unsafe {
|
||||
// we have to block the signal handler so that it doesn't cause an
|
||||
// infinite recursion of updating
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Creates a closure which checks if a button is toggled.
|
||||
fn s_flg<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)
|
||||
pub fn new(view: EditorView) -> Self
|
||||
{
|
||||
self.cause_refresh_view();
|
||||
self.cause_refresh_props();
|
||||
Self{view}
|
||||
}
|
||||
|
||||
/// Propagates updated map view information to widgets.
|
||||
pub fn cause_refresh_view(&self)
|
||||
pub fn open_new(&mut self)
|
||||
{
|
||||
unsafe {
|
||||
gtk_widget_queue_draw(*self.draw);
|
||||
}
|
||||
eprintln!("open_new");
|
||||
}
|
||||
|
||||
/// Propagates updated map property information to widgets.
|
||||
pub fn cause_refresh_props(&self)
|
||||
pub fn open_buf(&mut self, b: &[u8])
|
||||
{
|
||||
let inf = &self.cur_block().info;
|
||||
|
||||
each_flag(&self.fent, &O_ENT, r_flg(|&f| inf.entr_flags.contains(f)));
|
||||
each_flag(&self.fenv, &O_ENV, r_flg(|&f| inf.envi_flags.contains(f)));
|
||||
each_flag(&self.fmsn, &O_MSN, r_flg(|&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, s_flg(|&f, s| inf.entr_flags.set(f, s)));
|
||||
each_flag(&self.fenv, &O_ENV, s_flg(|&f, s| inf.envi_flags.set(f, s)));
|
||||
each_flag(&self.fmsn, &O_MSN, s_flg(|&f, s| inf.miss_flags.set(f, s)));
|
||||
|
||||
self.push_block(blk);
|
||||
self.cause_refresh_view();
|
||||
eprintln!("open_buf");
|
||||
}
|
||||
}
|
||||
|
||||
impl std::ops::Deref for MapEditor
|
||||
pub struct EditorPresenter
|
||||
{
|
||||
type Target = editor::MapEditor;
|
||||
|
||||
#[inline]
|
||||
fn deref(&self) -> &Self::Target {&self.edit}
|
||||
}
|
||||
|
||||
impl std::ops::DerefMut for MapEditor
|
||||
pub struct EditorView
|
||||
{
|
||||
#[inline]
|
||||
fn deref_mut(&mut self) -> &mut Self::Target {&mut self.edit}
|
||||
pub prop: PropertiesWindow,
|
||||
}
|
||||
|
||||
/// Specialized map editor which has callbacks for frontend purposes.
|
||||
pub struct MapEditor
|
||||
pub struct PropertiesWindow
|
||||
{
|
||||
pub edit: editor::MapEditor,
|
||||
pub draw: Refc<'static, GtkWidget>,
|
||||
pub fent: Vec<PropFlag>,
|
||||
pub fenv: Vec<PropFlag>,
|
||||
pub fmsn: Vec<PropFlag>,
|
||||
pub flg_ent: Vec<Refc<'static, GtkToggleButton>>,
|
||||
pub flg_env: Vec<Refc<'static, GtkToggleButton>>,
|
||||
pub flg_msn: Vec<Refc<'static, GtkToggleButton>>,
|
||||
}
|
||||
|
||||
/// A runtime reference to the map editor.
|
||||
pub type MapEditorRef = std::cell::RefCell<MapEditor>;
|
||||
|
||||
pub struct PropFlag
|
||||
pub struct EditorModel
|
||||
{
|
||||
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,
|
||||
];
|
||||
pub type EditorRef = std::cell::RefCell<EditorModel>;
|
||||
|
||||
// EOF
|
||||
|
|
|
@ -7,66 +7,38 @@ use gio_sys::*;
|
|||
use glib_sys::*;
|
||||
use gobject_sys::*;
|
||||
use gtk_sys::*;
|
||||
use maraiah::{c_str, durandal::ffi};
|
||||
use maraiah::{c_str,
|
||||
durandal::{err::*, ffi}};
|
||||
use std::{cell::RefCell, rc::Rc};
|
||||
|
||||
const APP_ID: ffi::NT = c_str!("net.greyserv.maraiah.tycho");
|
||||
const B_ADJ_M_HORZ: ffi::NT = c_str!("adj-map-horz");
|
||||
const B_ADJ_M_VERT: ffi::NT = c_str!("adj-map-vert");
|
||||
const B_BTN_ABOUT: ffi::NT = c_str!("btn-about");
|
||||
const B_BTN_M_PROP: ffi::NT = c_str!("btn-show-map-prop");
|
||||
const B_BTN_M_TOOL: ffi::NT = c_str!("btn-show-map-tools");
|
||||
const B_BTN_M_VIEW: ffi::NT = c_str!("btn-show-map-view");
|
||||
const B_BTN_NEW: ffi::NT = c_str!("btn-new");
|
||||
const B_BTN_OPEN: ffi::NT = c_str!("btn-open");
|
||||
const B_BTN_QUIT: ffi::NT = c_str!("btn-quit");
|
||||
const B_CON_F_ENT: ffi::NT = c_str!("con-f-ent");
|
||||
const B_CON_F_ENV: ffi::NT = c_str!("con-f-env");
|
||||
const B_CON_F_MSN: ffi::NT = c_str!("con-f-msn");
|
||||
const B_DLG_ABOUT: ffi::NT = c_str!("dlg-about");
|
||||
const B_DRAW_AREA: ffi::NT = c_str!("draw-area");
|
||||
const B_WIN_MAIN: ffi::NT = c_str!("win-main");
|
||||
const B_WIN_M_PROP: ffi::NT = c_str!("win-map-prop");
|
||||
const B_WIN_M_TOOL: ffi::NT = c_str!("win-map-tools");
|
||||
const B_WIN_M_VIEW: ffi::NT = c_str!("win-map-view");
|
||||
const E_ACTIVATE: ffi::NT = c_str!("activate");
|
||||
const E_DELETE: ffi::NT = c_str!("delete-event");
|
||||
const E_DESTROY: ffi::NT = c_str!("destroy");
|
||||
const E_DRAW: ffi::NT = c_str!("draw");
|
||||
const E_SHUTDOWN: ffi::NT = c_str!("shutdown");
|
||||
const E_TOGGLE: ffi::NT = c_str!("toggled");
|
||||
const IM_ABOUT: ffi::NT = c_str!("/net/greyserv/maraiah/tycho/tycho2.png");
|
||||
const IM_NOMAP: ffi::NT = c_str!("/net/greyserv/maraiah/tycho/tycho1.png");
|
||||
const PATH_BUILDER: ffi::NT = c_str!("/net/greyserv/maraiah/tycho/ui");
|
||||
const PATH_CSS: ffi::NT = c_str!("/net/greyserv/maraiah/tycho/css");
|
||||
|
||||
// Called when the application activates in order to set everything up.
|
||||
unsafe extern "C" fn app_activate(app: *mut GtkApplication, _: gpointer)
|
||||
{
|
||||
// Callback to finalize the reference.
|
||||
unsafe extern "C" fn c_done(_: *mut GApplication, ptr: gpointer)
|
||||
{
|
||||
let edit = Rc::from_raw(ptr as *const MapEditorRef);
|
||||
let edit = Rc::from_raw(ptr as *const EditorRef);
|
||||
assert_eq!(Rc::strong_count(&edit), 1);
|
||||
}
|
||||
|
||||
let b = Refc::new(gtk_builder_new_from_resource(PATH_BUILDER));
|
||||
|
||||
let edit = MapEditor{edit: Default::default(),
|
||||
draw: Refc::own(get_obj(&b, B_DRAW_AREA)),
|
||||
fent: get_flag_fields(&b, B_CON_F_ENT),
|
||||
fenv: get_flag_fields(&b, B_CON_F_ENV),
|
||||
fmsn: get_flag_fields(&b, B_CON_F_MSN)};
|
||||
let prop = PropertiesWindow{flg_ent: get_flag_fields(&b, B_CON_F_ENT),
|
||||
flg_env: get_flag_fields(&b, B_CON_F_ENV),
|
||||
flg_msn: get_flag_fields(&b, B_CON_F_MSN)};
|
||||
|
||||
let edit = EditorModel::new(EditorView{prop});
|
||||
let edit = RefCell::new(edit);
|
||||
let edit = Rc::new(edit);
|
||||
|
||||
setup_css();
|
||||
setup_toggles(edit.clone());
|
||||
setup_draw_area(&b, edit.clone());
|
||||
setup_win_map_view(&b);
|
||||
setup_win_map_tools(&b);
|
||||
setup_win_map_prop(&b);
|
||||
//setup_draw_area(&b, edit.clone());
|
||||
let wv = setup_win(&b, B_WIN_M_VIEW, B_BTN_M_VIEW);
|
||||
let wt = setup_win(&b, B_WIN_M_TOOL, B_BTN_M_TOOL);
|
||||
let _ = setup_win(&b, B_WIN_M_PROP, B_BTN_M_PROP);
|
||||
gtk_widget_show_all(wv);
|
||||
gtk_widget_show_all(wt);
|
||||
|
||||
setup_about_dlg(&b);
|
||||
setup_win_main(&b, app, edit.clone());
|
||||
|
||||
|
@ -74,7 +46,8 @@ unsafe extern "C" fn app_activate(app: *mut GtkApplication, _: gpointer)
|
|||
}
|
||||
|
||||
// Gets all of the toggle buttons from a container.
|
||||
unsafe fn get_flag_fields(b: &Refc<GtkBuilder>, name: ffi::NT) -> Vec<PropFlag>
|
||||
unsafe fn get_flag_fields(b: &Refc<GtkBuilder>, name: ffi::NT)
|
||||
-> Vec<Refc<'static, GtkToggleButton>>
|
||||
{
|
||||
let mut flags = Vec::new();
|
||||
|
||||
|
@ -82,127 +55,28 @@ unsafe fn get_flag_fields(b: &Refc<GtkBuilder>, name: ffi::NT) -> Vec<PropFlag>
|
|||
let head = ListD::new(gtk_container_get_children(head));
|
||||
let gtyp = gtk_toggle_button_get_type();
|
||||
|
||||
get_typed_from(head, gtyp, |obj| {
|
||||
flags.push(PropFlag{w: Refc::own(obj as _), h: 0});
|
||||
});
|
||||
get_typed_from(head, gtyp, |obj| flags.push(Refc::own(obj as _)));
|
||||
|
||||
flags
|
||||
}
|
||||
|
||||
// Connects toggle events to every flag in the map properties window.
|
||||
unsafe fn setup_toggles(edit: Rc<MapEditorRef>)
|
||||
{
|
||||
let mut ed = edit.borrow_mut();
|
||||
|
||||
connect_toggle(edit.clone(), ed.fent.iter_mut());
|
||||
connect_toggle(edit.clone(), ed.fenv.iter_mut());
|
||||
connect_toggle(edit.clone(), ed.fmsn.iter_mut());
|
||||
}
|
||||
|
||||
// Connects toggle events to each of the widgets in `it`.
|
||||
unsafe fn connect_toggle<'a, I>(edit: Rc<MapEditorRef>, it: I)
|
||||
where I: Iterator<Item = &'a mut PropFlag>
|
||||
{
|
||||
// Callback for when the button is toggled, which causates an update.
|
||||
unsafe extern "C" fn c_toggled(_: *mut GtkToggleButton, edit: gpointer)
|
||||
{
|
||||
let edit = &*(edit as *const MapEditorRef);
|
||||
edit.borrow_mut().cause_update_props();
|
||||
}
|
||||
|
||||
// go over each widget, set its object and callback handle
|
||||
for flg in it {
|
||||
let erf = connect_ref(*flg.w, edit.clone());
|
||||
flg.h = connect(*flg.w, E_TOGGLE, c_toggled as _, erf);
|
||||
}
|
||||
}
|
||||
|
||||
// Sets up the map view window's drawing area.
|
||||
unsafe fn setup_draw_area(b: &Refc<GtkBuilder>, edit: Rc<MapEditorRef>)
|
||||
{
|
||||
// All of the state necessary for the drawing area.
|
||||
struct RenderState
|
||||
{
|
||||
im_nomap: Refc<'static, GdkPixbuf>,
|
||||
ax: Refc<'static, GtkAdjustment>,
|
||||
ay: Refc<'static, GtkAdjustment>,
|
||||
edit: Rc<MapEditorRef>,
|
||||
}
|
||||
|
||||
// Callback to finalize the drawing area.
|
||||
unsafe extern "C" fn c_done(_: *mut GtkWidget, rend: gpointer)
|
||||
{
|
||||
Box::from_raw(rend as *mut RenderState);
|
||||
}
|
||||
|
||||
// Callback to draw on the drawing area.
|
||||
unsafe extern "C" fn c_draw(wid: *mut GtkWidget,
|
||||
ctx: *mut cairo_sys::cairo_t,
|
||||
rend: gpointer)
|
||||
-> gboolean
|
||||
{
|
||||
let rend = &mut *(rend as *mut RenderState);
|
||||
|
||||
let w = f64::from(gtk_widget_get_allocated_width(wid));
|
||||
let h = f64::from(gtk_widget_get_allocated_height(wid));
|
||||
|
||||
gtk_adjustment_set_lower(*rend.ax, 0.0);
|
||||
gtk_adjustment_set_upper(*rend.ax, w);
|
||||
|
||||
gtk_adjustment_set_lower(*rend.ay, 0.0);
|
||||
gtk_adjustment_set_upper(*rend.ay, h);
|
||||
|
||||
let im = CrImage(*rend.im_nomap);
|
||||
let mut dr = CrDrawArea::new(ctx, w, h);
|
||||
|
||||
rend.edit.borrow().draw(&mut dr, &im);
|
||||
|
||||
1
|
||||
}
|
||||
|
||||
let wid = get_obj::<GtkDrawingArea>(b, B_DRAW_AREA);
|
||||
|
||||
// get all of the necessary state and related objects
|
||||
let ax = Refc::own(get_obj(b, B_ADJ_M_HORZ));
|
||||
let ay = Refc::own(get_obj(b, B_ADJ_M_VERT));
|
||||
|
||||
let im_nomap = Refc::new(load_img(IM_NOMAP));
|
||||
|
||||
let rend = RenderState{im_nomap, ax, ay, edit};
|
||||
let rend = Box::into_raw(Box::new(rend));
|
||||
|
||||
connect(wid, E_DESTROY, c_done as _, rend);
|
||||
connect(wid, E_DRAW, c_draw as _, rend);
|
||||
}
|
||||
|
||||
// Sets up the map view window.
|
||||
unsafe fn setup_win_map_view(b: &Refc<GtkBuilder>)
|
||||
unsafe fn setup_win(b: &Refc<GtkBuilder>, win: ffi::NT, btn: ffi::NT)
|
||||
-> *mut GtkWidget
|
||||
{
|
||||
let win = get_obj::<GtkWindow >(b, B_WIN_M_VIEW);
|
||||
let btn = get_obj::<GtkMenuItem>(b, B_BTN_M_VIEW);
|
||||
// Callback to show the widget.
|
||||
unsafe extern "C" fn c_show_act(_: *mut GtkWidget, wid: gpointer)
|
||||
{
|
||||
gtk_widget_show_all(wid as _);
|
||||
}
|
||||
|
||||
let win = get_obj::<GtkWindow >(b, win);
|
||||
let btn = get_obj::<GtkMenuItem>(b, btn);
|
||||
|
||||
connect_hide(win);
|
||||
connect_show(btn, win);
|
||||
}
|
||||
connect(btn, E_ACTIVATE, c_show_act as _, win);
|
||||
|
||||
// Sets up the map tools window.
|
||||
unsafe fn setup_win_map_tools(b: &Refc<GtkBuilder>)
|
||||
{
|
||||
let win = get_obj::<GtkWindow >(b, B_WIN_M_TOOL);
|
||||
let btn = get_obj::<GtkMenuItem>(b, B_BTN_M_TOOL);
|
||||
|
||||
connect_hide(win);
|
||||
connect_show(btn, win);
|
||||
}
|
||||
|
||||
// Sets up the map properties window.
|
||||
unsafe fn setup_win_map_prop(b: &Refc<GtkBuilder>)
|
||||
{
|
||||
let win = get_obj::<GtkWindow >(b, B_WIN_M_PROP);
|
||||
let btn = get_obj::<GtkMenuItem>(b, B_BTN_M_PROP);
|
||||
|
||||
connect_hide(win);
|
||||
connect_show(btn, win);
|
||||
win as *mut GtkWidget
|
||||
}
|
||||
|
||||
// Sets up the about dialogue.
|
||||
|
@ -284,7 +158,7 @@ unsafe fn get_typed_from<I, F>(it: I, ty: GType, mut f: F)
|
|||
// Sets up the main menu window.
|
||||
unsafe fn setup_win_main(b: &Refc<GtkBuilder>,
|
||||
app: *mut GtkApplication,
|
||||
edit: Rc<MapEditorRef>)
|
||||
edit: Rc<EditorRef>)
|
||||
{
|
||||
// Callback to close the window when the "Quit" button is pressed.
|
||||
unsafe extern "C" fn c_quit_act(_: *mut GtkWidget, win: gpointer)
|
||||
|
@ -295,45 +169,30 @@ unsafe fn setup_win_main(b: &Refc<GtkBuilder>,
|
|||
// 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);
|
||||
let mut edit = edit.borrow_mut();
|
||||
let edit = &*(edit as *const EditorRef);
|
||||
|
||||
if edit.unclean() {
|
||||
let titl = c_str!("Confirm");
|
||||
let text = c_str!("Are you sure you want to create a new project? \
|
||||
Unsaved data may be lost.");
|
||||
edit.borrow_mut().open_new();
|
||||
}
|
||||
|
||||
if !run_ok_cancel_dlg(titl, text) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
// Opens the map editor with a buffer.
|
||||
unsafe fn open_buf(path: &str, edit: &mut EditorModel) -> ResultS<()>
|
||||
{
|
||||
let fp = std::fs::File::open(&path)?;
|
||||
let mm = memmap::Mmap::map(&fp)?;
|
||||
|
||||
edit.open_new();
|
||||
edit.cause_refresh();
|
||||
edit.open_buf(&mm);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
// Callback to open an existing map when the "Open" button is pressed.
|
||||
unsafe extern "C" fn c_open_act(_: *mut GtkWidget, edit: gpointer)
|
||||
{
|
||||
let edit = &*(edit as *const MapEditorRef);
|
||||
let mut edit = edit.borrow_mut();
|
||||
|
||||
if edit.unclean() {
|
||||
let titl = c_str!("Confirm");
|
||||
let text = c_str!("Are you sure you want to open this project? \
|
||||
Unsaved data may be lost.");
|
||||
|
||||
if !run_ok_cancel_dlg(titl, text) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
let edit = &*(edit as *const EditorRef);
|
||||
|
||||
if let Some(path) = run_file_chooser_open() {
|
||||
// TODO: handle errors gracefully
|
||||
let fp = std::fs::File::open(&path).unwrap();
|
||||
let mm = memmap::Mmap::map(&fp).unwrap();
|
||||
edit.open_buf(&mm);
|
||||
edit.cause_refresh();
|
||||
open_buf(&path, &mut edit.borrow_mut()).unwrap();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -367,32 +226,6 @@ unsafe fn setup_css()
|
|||
gtk_style_context_add_provider_for_screen(scr, *css as _, pri);
|
||||
}
|
||||
|
||||
// Runs a modal OK/Cancel dialogue.
|
||||
unsafe fn run_ok_cancel_dlg(title: ffi::NT, text: ffi::NT) -> bool
|
||||
{
|
||||
let flags = GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT;
|
||||
let dlg = gtk_dialog_new_with_buttons(title,
|
||||
ffi::null_mut(),
|
||||
flags,
|
||||
c_str!("_OK"),
|
||||
GTK_RESPONSE_ACCEPT,
|
||||
c_str!("_Cancel"),
|
||||
GTK_RESPONSE_REJECT,
|
||||
ffi::null_mut_void());
|
||||
|
||||
let area = gtk_dialog_get_content_area(dlg as _);
|
||||
let labl = gtk_label_new(text);
|
||||
|
||||
gtk_container_add(area as _, labl);
|
||||
gtk_widget_show_all(area as _);
|
||||
|
||||
let res = gtk_dialog_run(dlg as _);
|
||||
|
||||
gtk_widget_destroy(dlg);
|
||||
|
||||
res == GTK_RESPONSE_ACCEPT
|
||||
}
|
||||
|
||||
// Runs a modal Open File dialogue.
|
||||
unsafe fn run_file_chooser_open() -> Option<String>
|
||||
{
|
||||
|
@ -440,26 +273,13 @@ unsafe fn connect_hide<T>(wid: *mut T)
|
|||
connect(wid, E_DELETE, c_hide_del as _, ffi::null_void());
|
||||
}
|
||||
|
||||
// Connects a handler that shows a widget when activated.
|
||||
unsafe fn connect_show<T, U>(btn: *mut T, wid: *mut U)
|
||||
{
|
||||
// Callback to show the widget.
|
||||
unsafe extern "C" fn c_show_act(_: *mut GtkWidget, wid: gpointer)
|
||||
{
|
||||
gtk_widget_show_all(wid as _);
|
||||
}
|
||||
|
||||
connect(btn, E_ACTIVATE, c_show_act as _, wid);
|
||||
}
|
||||
|
||||
// Connects the map editor reference to a widget.
|
||||
unsafe fn connect_ref<T>(obj: *mut T, rc: Rc<MapEditorRef>)
|
||||
-> *const MapEditorRef
|
||||
unsafe fn connect_ref<T>(obj: *mut T, rc: Rc<EditorRef>) -> *const EditorRef
|
||||
{
|
||||
// Callback to finalize the reference.
|
||||
unsafe extern "C" fn c_done(_: *mut GtkWidget, ptr: gpointer)
|
||||
{
|
||||
Rc::from_raw(ptr as *const MapEditorRef);
|
||||
Rc::from_raw(ptr as *const EditorRef);
|
||||
}
|
||||
|
||||
let ptr = Rc::into_raw(rc);
|
||||
|
@ -521,4 +341,34 @@ fn main()
|
|||
}
|
||||
}
|
||||
|
||||
const APP_ID: ffi::NT = c_str!("net.greyserv.maraiah.tycho");
|
||||
const B_ADJ_M_HORZ: ffi::NT = c_str!("adj-map-horz");
|
||||
const B_ADJ_M_VERT: ffi::NT = c_str!("adj-map-vert");
|
||||
const B_BTN_ABOUT: ffi::NT = c_str!("btn-about");
|
||||
const B_BTN_M_PROP: ffi::NT = c_str!("btn-show-map-prop");
|
||||
const B_BTN_M_TOOL: ffi::NT = c_str!("btn-show-map-tools");
|
||||
const B_BTN_M_VIEW: ffi::NT = c_str!("btn-show-map-view");
|
||||
const B_BTN_NEW: ffi::NT = c_str!("btn-new");
|
||||
const B_BTN_OPEN: ffi::NT = c_str!("btn-open");
|
||||
const B_BTN_QUIT: ffi::NT = c_str!("btn-quit");
|
||||
const B_CON_F_ENT: ffi::NT = c_str!("con-f-ent");
|
||||
const B_CON_F_ENV: ffi::NT = c_str!("con-f-env");
|
||||
const B_CON_F_MSN: ffi::NT = c_str!("con-f-msn");
|
||||
const B_DLG_ABOUT: ffi::NT = c_str!("dlg-about");
|
||||
const B_DRAW_AREA: ffi::NT = c_str!("draw-area");
|
||||
const B_WIN_MAIN: ffi::NT = c_str!("win-main");
|
||||
const B_WIN_M_PROP: ffi::NT = c_str!("win-map-prop");
|
||||
const B_WIN_M_TOOL: ffi::NT = c_str!("win-map-tools");
|
||||
const B_WIN_M_VIEW: ffi::NT = c_str!("win-map-view");
|
||||
const E_ACTIVATE: ffi::NT = c_str!("activate");
|
||||
const E_DELETE: ffi::NT = c_str!("delete-event");
|
||||
const E_DESTROY: ffi::NT = c_str!("destroy");
|
||||
const E_DRAW: ffi::NT = c_str!("draw");
|
||||
const E_SHUTDOWN: ffi::NT = c_str!("shutdown");
|
||||
const E_TOGGLE: ffi::NT = c_str!("toggled");
|
||||
const IM_ABOUT: ffi::NT = c_str!("/net/greyserv/maraiah/tycho/tycho2.png");
|
||||
const IM_NOMAP: ffi::NT = c_str!("/net/greyserv/maraiah/tycho/tycho1.png");
|
||||
const PATH_BUILDER: ffi::NT = c_str!("/net/greyserv/maraiah/tycho/ui");
|
||||
const PATH_CSS: ffi::NT = c_str!("/net/greyserv/maraiah/tycho/css");
|
||||
|
||||
// EOF
|
||||
|
|
Loading…
Reference in New Issue