1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
use crate::{
    edit_list::SelectionList,
    feature_types::{Grab, StringSearcher, ViewMode},
    node::NodeContainer,
    node_settings::NodeSettings,
    state_info::StateInfo,
    vector::Vector,
};

use copypasta::ClipboardContext;
use petri_net_simulation::{DynamicNet, MultiPetriNetSimulation};
use pns::Net;

use std::path::PathBuf;

/// This represents the editor you want to use to edit and display petri nets.
pub struct Editor {
    net: DynamicNet<MultiPetriNetSimulation>,
    text_content_shown: bool,
    nodes: NodeContainer,
    transition_context: Vec<Box<str>>,
    window_size: Vector,
    zoom: f32,
    selected: SelectionList,
    grab: Option<Grab>,
    view_mode: ViewMode,
    net_path: Option<PathBuf>,
    state_infos: Vec<StateInfo>,
    simulation: usize,
    mouse_pos: Vector,
    view_offset: Vector,
    clipboard: Option<ClipboardContext>,
    string_searcher: Option<StringSearcher>,
    changes: bool,
    snapping: Option<f32>,
    node_settings: NodeSettings,
}

impl Editor {
    /// Creates a new editor, which contains a renderer and knows about the window size.
    pub fn new(width: f32, height: f32, node_settings: NodeSettings) -> Self {
        let net = Net::new();

        Self {
            net: net.into(),
            text_content_shown: false,
            nodes: NodeContainer::empty(),
            transition_context: Vec::new(),
            window_size: Vector::new(width, height),
            zoom: 1.0,
            selected: SelectionList::new(),
            grab: None,
            view_mode: ViewMode::Default,
            net_path: None,
            state_infos: Vec::new(),
            simulation: 0,
            mouse_pos: Vector::new(0.0, 0.0),
            view_offset: Vector::new(0.0, 0.0),
            string_searcher: None,
            clipboard: ClipboardContext::new().ok(),
            changes: false,
            snapping: Some(16.0),
            node_settings,
        }
    }

    fn relative_mouse_pos(&self) -> Vector {
        (self.mouse_pos - self.window_size / 2.0) * self.zoom + self.view_offset
    }

    /// Indicates if snapping is enabled.
    pub fn snapping(&self) -> bool {
        self.snapping.is_some()
    }

    /// Indicates if the editor can be shown.
    pub fn text_editor_shown(&self) -> bool {
        self.text_content_shown
    }

    /// Indicates if the simuliton mode is active.
    pub fn simulation_mode(&self) -> bool {
        self.net.simulated().is_some()
    }

    /// Indicates if the search mode is active.
    pub fn search_mode(&self) -> bool {
        self.string_searcher.is_some()
    }

    /// Access the current view mode.
    pub fn view_mode(&self) -> ViewMode {
        self.view_mode
    }
}

mod input;
mod render;
mod update;