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}