Use global state
This commit is contained in:
52
src/main.rs
52
src/main.rs
@@ -9,14 +9,18 @@ extern crate image;
|
||||
use image::io::Reader as ImageReader;
|
||||
use image::{ DynamicImage };
|
||||
|
||||
use state::Storage;
|
||||
|
||||
use std::collections::{HashMap, HashSet};
|
||||
|
||||
use std::cell::RefCell;
|
||||
use std::rc::Rc;
|
||||
use std::sync::Mutex;
|
||||
|
||||
use std::io::{ Write, Read, Cursor };
|
||||
use std::fs::File;
|
||||
|
||||
//////////////////// Global State ////////////////////
|
||||
// Don't @ me...
|
||||
static STATE: Storage<Mutex<AppState>> = Storage::new();
|
||||
|
||||
//////////////////// Data Layout ////////////////////
|
||||
|
||||
@@ -131,14 +135,16 @@ fn node_create_dialog(state: &mut AppState, pos_x: f32, pos_y: f32) {
|
||||
mod dispatch {
|
||||
use super::*;
|
||||
type Coords = (f32, f32);
|
||||
pub(super) fn node_press(state: &mut AppState, coords: Coords) {
|
||||
pub(super) fn node_press(coords: Coords) {
|
||||
let (pos_x, pos_y) = coords;
|
||||
if app::event_button() == 1 {
|
||||
let name = dialog::input_default("Node", "");
|
||||
if let Some(name) = name {
|
||||
let mut state = STATE.get().lock().unwrap();
|
||||
state.board.add_node(pos_x, pos_y, name);
|
||||
}
|
||||
} else if app::event_button() == 3 {
|
||||
let mut state = STATE.get().lock().unwrap();
|
||||
let id = state.board.nearest_node(pos_x, pos_y);
|
||||
if let Some(id) = id {
|
||||
state.board.remove_node(id);
|
||||
@@ -146,8 +152,9 @@ mod dispatch {
|
||||
}
|
||||
app::redraw();
|
||||
}
|
||||
pub(super) fn edge_press(state: &mut AppState, coords: Coords) {
|
||||
pub(super) fn edge_press(coords: Coords) {
|
||||
let (pos_x, pos_y) = coords;
|
||||
let mut state = STATE.get().lock().unwrap();
|
||||
if app::event_button() == 1 {
|
||||
match (state.selected_node, state.board.nearest_node(pos_x, pos_y)) {
|
||||
(Some(selected), Some(nearest)) => {
|
||||
@@ -218,7 +225,7 @@ impl CoordTransformer for frame::Frame {
|
||||
}
|
||||
|
||||
//////////////////// App State ////////////////////
|
||||
|
||||
#[derive(Clone, Copy)]
|
||||
enum EditMode {
|
||||
Node,
|
||||
Edge,
|
||||
@@ -245,6 +252,8 @@ impl AppState {
|
||||
//////////////////// Procedural App Creation ////////////////////
|
||||
|
||||
fn main() {
|
||||
// State
|
||||
STATE.set(Mutex::new(AppState::new()));
|
||||
// App setup
|
||||
let app = app::App::default()
|
||||
.with_scheme(app::Scheme::Gtk);
|
||||
@@ -255,17 +264,12 @@ fn main() {
|
||||
.size_of_parent();
|
||||
flex.set_type(group::FlexType::Column);
|
||||
|
||||
// State
|
||||
let state = Rc::new(RefCell::new(AppState::new()));
|
||||
|
||||
// Menu
|
||||
let mut menubar = menu::MenuBar::default();
|
||||
let state_clone = Rc::clone(&state);
|
||||
menubar.add("File/New", Shortcut::None, menu::MenuFlag::Normal, move |_| {
|
||||
state_clone.replace(AppState::new());
|
||||
*STATE.get().lock().unwrap() = AppState::new();
|
||||
app::redraw();
|
||||
});
|
||||
let state_clone = Rc::clone(&state);
|
||||
menubar.add("File/Open...", Shortcut::None, menu::MenuFlag::Normal, move |_| {
|
||||
let mut fc = dialog::NativeFileChooser::new(dialog::NativeFileChooserType::BrowseFile);
|
||||
fc.show();
|
||||
@@ -285,9 +289,8 @@ fn main() {
|
||||
state.image_raw = Some(image);
|
||||
app::redraw();
|
||||
}
|
||||
state_clone.replace(state);
|
||||
*STATE.get().lock().unwrap() = state;
|
||||
});
|
||||
let state_clone = Rc::clone(&state);
|
||||
menubar.add("File/Open Image...", Shortcut::None, menu::MenuFlag::Normal, move |_| {
|
||||
let mut fc = dialog::NativeFileChooser::new(dialog::NativeFileChooserType::BrowseFile);
|
||||
fc.show();
|
||||
@@ -295,7 +298,7 @@ fn main() {
|
||||
|
||||
match ImageReader::open(filename).map(|i| i.decode()) {
|
||||
Ok(Ok(image)) => {
|
||||
let mut state = state_clone.borrow_mut();
|
||||
let mut state = STATE.get().lock().unwrap();
|
||||
let data = encode_png(&image);
|
||||
state.image = Some(PngImage::from_data(&data).unwrap());
|
||||
state.image_raw = Some(image);
|
||||
@@ -304,7 +307,6 @@ fn main() {
|
||||
_ => dialog::alert_default("Error opening file"),
|
||||
}
|
||||
});
|
||||
let state_clone = Rc::clone(&state);
|
||||
menubar.add("File/Save As ...", Shortcut::None, menu::MenuFlag::Normal, move |_| {
|
||||
let mut fc = dialog::NativeFileChooser::new(dialog::NativeFileChooserType::BrowseSaveFile);
|
||||
fc.show();
|
||||
@@ -312,7 +314,7 @@ fn main() {
|
||||
let file = File::create(fc.filename()).unwrap();
|
||||
let mut ar = zip::ZipWriter::new(file);
|
||||
let options = zip::write::FileOptions::default();
|
||||
let state = state_clone.borrow();
|
||||
let mut state = STATE.get().lock().unwrap();
|
||||
|
||||
ar.start_file("graph.json", options).ok();
|
||||
ar.write(&serde_json::to_vec(&state.board).unwrap()).ok();
|
||||
@@ -324,14 +326,12 @@ fn main() {
|
||||
}
|
||||
ar.finish().ok();
|
||||
});
|
||||
let state_clone = Rc::clone(&state);
|
||||
menubar.add("Edit/Edit Nodes", Shortcut::None, menu::MenuFlag::Normal, move |_| {
|
||||
let mut state = state_clone.borrow_mut();
|
||||
let mut state = STATE.get().lock().unwrap();
|
||||
state.edit_mode = EditMode::Node;
|
||||
});
|
||||
let state_clone = Rc::clone(&state);
|
||||
menubar.add("Edit/Edit Edges", Shortcut::None, menu::MenuFlag::Normal, move |_| {
|
||||
let mut state = state_clone.borrow_mut();
|
||||
let mut state = STATE.get().lock().unwrap();
|
||||
state.edit_mode = EditMode::Edge;
|
||||
});
|
||||
|
||||
@@ -339,10 +339,9 @@ fn main() {
|
||||
|
||||
// Canvas
|
||||
let mut frame = frame::Frame::default();
|
||||
let state_clone = Rc::clone(&state);
|
||||
frame.draw(move |f| {
|
||||
use draw::*;
|
||||
let mut state = state_clone.borrow_mut();
|
||||
let mut state = STATE.get().lock().unwrap();
|
||||
// Background
|
||||
let image = &mut state.image;
|
||||
if let Some(image) = image.as_mut() {
|
||||
@@ -369,16 +368,15 @@ fn main() {
|
||||
}
|
||||
}
|
||||
});
|
||||
let state_clone = Rc::clone(&state);
|
||||
frame.handle(move |f, e| {
|
||||
match e {
|
||||
Event::Push => {
|
||||
let mut state = state_clone.borrow_mut();
|
||||
let edit_mode = STATE.get().lock().unwrap().edit_mode;
|
||||
let coords = f.to_coords(app::event_x(), app::event_y());
|
||||
|
||||
match state.edit_mode {
|
||||
EditMode::Node => dispatch::node_press(&mut state, coords),
|
||||
EditMode::Edge => dispatch::edge_press(&mut state, coords),
|
||||
match edit_mode {
|
||||
EditMode::Node => dispatch::node_press(coords),
|
||||
EditMode::Edge => dispatch::edge_press(coords),
|
||||
}
|
||||
true
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user