editor/
lib.rs

1#![deny(missing_docs)]
2
3//! Editor interface.
4
5use std::any::Any;
6
7/// A generic interface for editors, implemented on controllers.
8///
9/// Provides all information necessary to execute actions,
10/// select objects, navigate and update.
11/// This makes it possible to write reusable generic actions.
12///
13/// Methods that returns `Result` can trigger a rollback in actions.
14/// This is to prevent logical errors from affecting data.
15/// Concurrent actions are not permitted at the same time.
16///
17/// View information must be stored internally in the editor.
18/// If the editor state depends on the view state, then it should not be
19/// updated before `refresh_views` is called.
20pub trait Editor {
21    /// Gets the current cursor position in 2D.
22    fn cursor_2d(&self) -> Option<[f64; 2]>;
23    /// Gets the current cursor position in 3D world coordinates.
24    fn cursor_3d(&self) -> Option<[f64; 3]>;
25    /// Try to hit objects at 2D position.
26    fn hit_2d(&self, pos: [f64; 2]) -> Vec<(Type, Object)>;
27    /// Try to hit objects at 3D position.
28    fn hit_3d(&self, pos: [f64; 3]) -> Vec<(Type, Object)>;
29    /// Select a single object.
30    fn select(&mut self, ty: Type, obj: Object) -> Result<(), ()>;
31    /// Select multiple objects.
32    /// Adds to the current selection.
33    fn select_multiple(&mut self, ty: Type, objs: &[Object]) -> Result<(), ()>;
34    /// Deselect multiple objects.
35    /// Removes from the current selection.
36    fn deselect_multiple(&mut self, ty: Type, objs: &[Object]) -> Result<(), ()>;
37    /// Deselect everything of a type.
38    fn select_none(&mut self, ty: Type) -> Result<(), ()>;
39    /// Inserts a new object.
40    fn insert(&mut self, ty: Type, args: &Any) -> Result<Object, ()>;
41    /// Returns an object which references must be updated when
42    /// using swap-remove by replacing object with last one in same table.
43    fn delete(&mut self, ty: Type, obj: Object) -> Result<(), ()>;
44    /// Updates an object with new values.
45    fn update(&mut self, ty: Type, obj: Object, args: &Any) -> Result<(), ()>;
46    /// Replaces an object with another.
47    fn replace(&mut self, ty: Type, from: Object, to: Object) -> Result<(), ()>;
48    /// Get the value of an object.
49    fn get<'a>(&'a self, ty: Type, obj: Object) -> Result<&'a Any, ()>;
50    /// Get the visible objects of a type.
51    fn visible(&self, ty: Type) -> Vec<Object>;
52    /// Gets the selected object of a type.
53    /// If the editor supports multiple selection,
54    /// the selected object is usually the among the multiple-selected ones.
55    fn selected(&self, ty: Type) -> Option<Object>;
56    /// Gets the multiple selected objects of a type.
57    /// The order of the selected objects matter.
58    fn multiple_selected(&self, ty: Type) -> Vec<Object>;
59    /// Get all objects of a type.
60    fn all(&self, ty: Type) -> Vec<Object>;
61    /// Navigate to an object such that it becomes visible.
62    fn navigate_to(&mut self, ty: Type, obj: Object) -> Result<(), ()>;
63}
64
65/// The type of an object.
66/// This does not have be unique for Rust types.
67/// Dynamically typed objects should use same id.
68#[derive(Clone, Copy, Debug)]
69pub struct Type(pub &'static str);
70/// The object id.
71#[derive(Clone, Copy, Debug)]
72pub struct Object(pub usize);
73
74/// A helper function for `Editor::delete` implementation.
75pub fn delete<T>(items: &mut Vec<T>, obj: Object) -> Result<Option<Object>, ()> {
76    if items.len() == 0 { return Err(()); }
77
78    let upd_obj = if obj.0 == items.len() - 1 {
79        // The deleted object was last, no update needed.
80        None
81    } else {
82        // Update references to the last object,
83        // which now takes the place of the deleted object.
84        Some(Object(items.len() - 1))
85    };
86    items.swap_remove(obj.0);
87    Ok(upd_obj)
88}
89
90/// A helper function for `Editor::update` implementation.
91pub fn update<T: Any + Clone>(items: &mut Vec<T>, obj: Object, args: &Any)
92-> Result<(), ()> {
93    match args.downcast_ref::<T>() {
94        None => { return Err(()); }
95        Some(val) => {
96            items[obj.0] = val.clone();
97            Ok(())
98        }
99    }
100}
101
102/// A helper function for `Editor::all` implementation.
103pub fn all<T>(items: &Vec<T>) -> Vec<Object> {
104    (0..items.len()).map(|i| Object(i)).collect()
105}
106
107/// A helper function for `Editor::get` implementation.
108pub fn get<T: Any>(items: &Vec<T>, obj: Object) -> Result<&Any, ()> {
109    Ok(try!(items.get(obj.0).ok_or(())))
110}