ViewSystem.js 7.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356
  1. import React from 'react';
  2. import {TreeNode, Tree} from '../helpers/tree'
  3. import Row from '../../modules/Row';
  4. import Col from '../../modules/Col';
  5. import BaseHolder from '../../modules/BaseHolder';
  6. import {View as Div, StyleSheet} from 'react-native';
  7. function log(...m) {
  8. console.log(...m);
  9. }
  10. export class ViewNode extends TreeNode {
  11. constructor(id,value, props, namespace = "default"){
  12. super(id);
  13. this.value = value; // constructor Component
  14. this.namespace = namespace;
  15. this.props = props || {};
  16. }
  17. }
  18. export class Node extends TreeNode {
  19. constructor(id, props, content) {
  20. super(id);
  21. this.ctor = BaseHolder;
  22. this.props = props || {};
  23. if(content){
  24. this.content = content; // this is a viewNode
  25. }
  26. }
  27. export() {
  28. delete this.props.selected;
  29. return super.export();
  30. }
  31. }
  32. export default class ViewSystem {
  33. constructor(CS) {
  34. this.views = {};
  35. this.CoreSystem = CS;
  36. this.ModuleSystem = CS.ModuleSystem;
  37. this.EventSystem = CS.EventSystem;
  38. this.ghosts = {};
  39. }
  40. getNode(ViewId, NodeId) {
  41. return this.views[ViewId].getNode(NodeId);
  42. }
  43. getView(name) {
  44. return this.views[name];
  45. }
  46. addView(name, view) {
  47. this.views[name] = view;
  48. return view;
  49. }
  50. removeView(name) {
  51. let view = this.views[name];
  52. delete this.views[name];
  53. return view;
  54. }
  55. render(name) {
  56. return this.views[name].render(this.CoreSystem);
  57. }
  58. renderModule(mod, id) {
  59. let selfView = this.CoreSystem.getCurrentView();
  60. let nodeId = "___"+id+"Node";
  61. let {
  62. value,
  63. props,
  64. namespace
  65. } = mod;
  66. if(!selfView.ghosts[nodeId]) {
  67. let viewNode = new ViewNode(id, value, props, namespace);
  68. let node = new Node(nodeId, {}, viewNode);
  69. selfView.ghosts[nodeId] = node;
  70. }
  71. let vn = selfView.ghosts[nodeId].content;
  72. vn.value = value;
  73. vn.namespace = namespace;
  74. let ViewNodeReact = renderContent(selfView.ghosts[nodeId], this.CoreSystem, selfView);
  75. return renderNode(selfView.ghosts[nodeId], this.CoreSystem, ViewNodeReact);
  76. }
  77. export() {
  78. let views = {};
  79. for(var i in this.views) {
  80. views[i] = this.views[i].export();
  81. }
  82. return {
  83. views
  84. }
  85. }
  86. import(data) {
  87. let { views } = data;
  88. for(var i in views) {
  89. this.views[i] = new View().import(views[i]);
  90. }
  91. return this;
  92. }
  93. ray(viewId, x, y, id) {
  94. let tree = this.views[viewId].ViewTree;
  95. }
  96. }
  97. export class View {
  98. constructor(){
  99. this.ViewTree = new Tree();
  100. let rootNode = new Node(Math.random(), {stretchContainer: false, selected: true}); // row
  101. this.addViewNode(rootNode);
  102. this.defaultContainer = rootNode;
  103. this.ghosts = {};
  104. }
  105. getDefaultContainer() {
  106. return this.defaultContainer;
  107. }
  108. getRoot() {
  109. return this.ViewTree.root;
  110. }
  111. getNode(id) {
  112. return this.ghosts[id] || this.ViewTree.getNode(id);
  113. }
  114. has(node) {
  115. if (typeof node !== "object") return this.getNode(node);
  116. return this.getNode(node.id);
  117. }
  118. render(CS) {
  119. let node = this.ViewTree.root;
  120. return (<Renderer CoreSystem={CS} node={node} tree={this.ViewTree} selfView={this}/>);
  121. }
  122. addViewNode(node,parentNode = null){
  123. this.ViewTree.insert(node,parentNode);
  124. return this;
  125. }
  126. setContent(content, container) {
  127. container.content = content;
  128. return this;
  129. }
  130. getParent(node) {
  131. if(!this.has(node)) return false;
  132. return this.getNode(this.ViewTree.getParent(node));
  133. }
  134. getRows(column) {
  135. log("Deprecated for now")
  136. return true;
  137. if(!column.isCol) {
  138. throw new Error("You must pass a ColNode to this function");
  139. }
  140. return this.getChildren(column);
  141. }
  142. setRows(column, rows = 1) {
  143. log("Deprecated for now")
  144. return true;
  145. if(!column.isCol) throw new Error("You must pass a ColNode to this function");
  146. if(rows < 1) throw new Error("Only positive rows");
  147. let colChildren = this.getChildren(column);
  148. if (colChildren.length > rows) {
  149. for(var i = rows; i < colChildren.length; i++) {
  150. let row = colChildren[i];
  151. if(row.content) {
  152. if(confirm("Are you sure you want to remove this row it has content?"))
  153. this.remove(row);
  154. } else {
  155. this.remove(row); }
  156. }
  157. } else {
  158. for(var i = colChildren.length; i < rows; i++)
  159. this.addViewNode(new Node(Math.random(), true), column); // row
  160. }
  161. return this.getRows(column);
  162. }
  163. getColumns(row) {
  164. log("Deprecated for now")
  165. return true;
  166. if(!row.isRow) {
  167. throw new Error("You must pass a RowNode to this function");
  168. }
  169. return this.getChildren(row);
  170. }
  171. setColumns(row, columns = 1) {
  172. log("Deprecated for now")
  173. return true;
  174. if(!row.isRow) throw new Error("You must pass a RowNode to this function");
  175. if(columns < 1) throw new Error("Only positive cols");
  176. let rowChildren = this.getChildren(row);
  177. if (rowChildren.length > columns) {
  178. for(var i = columns; i < rowChildren.length; i++) {
  179. let col = rowChildren[i];
  180. if(col.content) {
  181. if(confirm("Are you sure you want to remove this col it has content?"))
  182. this.remove(col);
  183. } else {
  184. this.remove(col);
  185. }
  186. }
  187. } else {
  188. for(var i = rowChildren.length; i < columns; i++) {
  189. this.addViewNode(new Node(Math.random()), row);
  190. }
  191. }
  192. return this.getColumns(row);
  193. }
  194. addGrid(column, rowSize, columnSize) {
  195. log("Deprecated for now")
  196. return true;
  197. this.setRows(column, rowSize)
  198. .forEach(row => this.setColumns(row, columnSize)
  199. .forEach(col => col.content = new ViewNode(
  200. Math.random(),
  201. "BaseContainer",
  202. {}
  203. )));
  204. }
  205. remove(node) {
  206. if(node === root) {
  207. console.log("Cannot remove Root node", node);
  208. return this;
  209. }
  210. this.ViewTree.remove(node);
  211. return this;
  212. }
  213. replace(oldNode,newNode){
  214. this.ViewTree.replaceNode(oldNode,newNode);
  215. return this;
  216. }
  217. getChildren(node) {
  218. return this.ViewTree.getChildren(node);
  219. }
  220. import(data, parentNode) {
  221. let { tree, ghosts } = data;
  222. if(!parentNode)
  223. this.ViewTree = new Tree();
  224. try {
  225. this.ViewTree.import(tree, Node, parentNode);
  226. this.defaultContainer = this.ViewTree.root;
  227. for(var i in ghosts) {
  228. this.ghosts[i] = new Node().import(ghosts[i]);
  229. }
  230. } catch(e) {
  231. log(e);
  232. throw new Error("ViewSystem import error : ", e);
  233. }
  234. return this;
  235. }
  236. export(node) {
  237. let tree = this.ViewTree.export(node);
  238. let ghostsExported = {};
  239. for(var i in this.ghosts) {
  240. ghostsExported[i] = this.ghosts[i].export();
  241. }
  242. return {
  243. tree,
  244. ghosts: ghostsExported
  245. };
  246. }
  247. }
  248. /// Node = Container -> Everywhere Containers
  249. // Content is Node.content Container property.
  250. // When Content is present, Container for Containers is stretchedToContent
  251. // IF NOT -> just be placed there.
  252. //
  253. let Renderer = (props) => {
  254. let { node , tree, CoreSystem, selfView } = props;
  255. let childrens = tree.getChildren(node);
  256. let childrenReact = childrens.map(child => {
  257. return(
  258. <Renderer node = {child}
  259. tree={tree}
  260. key={child.id}
  261. CoreSystem={CoreSystem}
  262. selfView={selfView} />)
  263. });
  264. let ModuleSystem = CoreSystem.ModuleSystem;
  265. let EventSystem = CoreSystem.EventSystem;
  266. let viewNode = node.content;
  267. let ViewNodeReact;
  268. // IF CONTENT
  269. if(viewNode) {
  270. ViewNodeReact = renderContent(node, CoreSystem, selfView);
  271. }
  272. return renderNode(node, CoreSystem, ViewNodeReact, childrenReact);
  273. }
  274. let renderNode = (node, CoreSystem, ViewNodeReact, childrenReact) => {
  275. CoreSystem.ModuleSystem.createRef(node.id);
  276. return CoreSystem.ModuleSystem.createElementCtor(
  277. node.ctor,
  278. {
  279. ...node.props,
  280. depth: node.depth,
  281. content: ViewNodeReact,
  282. ID: node.id,
  283. CoreSystem: CoreSystem
  284. },
  285. childrenReact,
  286. node.id
  287. );
  288. }
  289. let renderContent = (node, CoreSystem, selfView) => {
  290. let viewNode = node.content;
  291. // Create ref
  292. CoreSystem.ModuleSystem.createRef(viewNode.id);
  293. // Crete element
  294. return CoreSystem.ModuleSystem.createElement(
  295. viewNode.value,
  296. {
  297. ...viewNode.props,
  298. ModuleID: viewNode.id,
  299. NodeID: node.id,
  300. EventSystem: CoreSystem.EventSystem,
  301. CoreSystem: CoreSystem,
  302. View: selfView
  303. },
  304. null, // children
  305. viewNode.namespace,
  306. viewNode.id
  307. );
  308. }
  309. const styles = StyleSheet.create({
  310. colWrapper: {
  311. "position": "absolute",
  312. "left": 0,
  313. "bottom": 0,
  314. "right": 0,
  315. "top": 0
  316. }
  317. })