diff --git a/Editor/src/app/ConsoleViewer/consoleViewer.component.ts b/Editor/src/app/ConsoleViewer/consoleViewer.component.ts
new file mode 100644
index 0000000..3d6bfc5
--- /dev/null
+++ b/Editor/src/app/ConsoleViewer/consoleViewer.component.ts
@@ -0,0 +1,43 @@
+import { Component, Inject, ComponentRef, Injectable } from '@angular/core';
+import { GoldenLayoutComponentState, GlOnResize, GlOnHide, GlOnShow, GoldenLayoutContainer } from 'ng-golden-layout';
+import * as GoldenLayout from 'golden-layout';
+
+
+@Component({
+ selector: 'console-viewer',
+ templateUrl: './consoleViewer.html',
+ styleUrls: ['./consoleViewer.scss']
+})
+
+
+export class ConsoleViewerComponent implements GlOnResize, GlOnHide, GlOnShow {
+ public static containerManager: GoldenLayout.Container;
+
+ constructor(@Inject(GoldenLayoutComponentState) private state: any,
+ @Inject(GoldenLayoutContainer) private container: GoldenLayout.Container) {
+ ConsoleViewerComponent.containerManager = container;
+ }
+
+ ngOnInit() {
+ }
+
+ public onInput(e: Event): void {
+ console.log('Game Object Properties state saved.');
+ }
+
+ public glOnResize(): void {
+ console.log('Game Object Properties Resizing!');
+ }
+
+ public glOnShow(): void {
+ console.log('Game Object Properties Showing!');
+ }
+
+ public glOnHide(): void {
+ console.log('Game Object Properties Hiding!');
+ }
+
+ public ngOnDestroy() {
+ var stop = 0;
+ }
+}
\ No newline at end of file
diff --git a/Editor/src/app/ConsoleViewer/consoleViewer.html b/Editor/src/app/ConsoleViewer/consoleViewer.html
new file mode 100644
index 0000000..e69de29
diff --git a/Editor/src/app/ConsoleViewer/consoleViewer.scss b/Editor/src/app/ConsoleViewer/consoleViewer.scss
new file mode 100644
index 0000000..e69de29
diff --git a/Editor/src/app/HierachyViewer/hierachyViewer.component.ts b/Editor/src/app/HierachyViewer/hierachyViewer.component.ts
index f1c2e0f..eea0ef9 100644
--- a/Editor/src/app/HierachyViewer/hierachyViewer.component.ts
+++ b/Editor/src/app/HierachyViewer/hierachyViewer.component.ts
@@ -1,42 +1,49 @@
-import { Component, Inject } from '@angular/core';
+import { Component, Inject, AfterContentInit } from '@angular/core';
import { GoldenLayoutComponentState, GlOnResize, GlOnHide, GlOnShow, GoldenLayoutContainer } from 'ng-golden-layout';
+import { UndoRedoManagerService, UndoRedoAction } from '../../assets/Utils/UndoRedo/UndoRedoManager.service';
import * as GoldenLayout from 'golden-layout';
@Component({
- selector: 'hierachy-viewer',
- template: `
-
- This is for the Hierachy viewer
+ selector: 'hierachy-viewer',
+ template: `
+
+ This is for the Hierachy viewer
`
})
-export class HierachyViewerComponent implements GlOnResize, GlOnHide, GlOnShow {
- constructor(@Inject(GoldenLayoutComponentState) private state: any,
- @Inject(GoldenLayoutContainer) private container: GoldenLayout.Container) {}
+@Inject(GoldenLayoutContainer)
+export class HierachyViewerComponent implements GlOnResize, GlOnHide, GlOnShow{
+ public static containerManager : GoldenLayout.Container;
- public onInput(e: Event): void {
-
- this.container.extendState({
- value: (
e.target).value
- });
+ constructor(@Inject(GoldenLayoutComponentState) private state: any,
+ @Inject(GoldenLayoutContainer) private container: GoldenLayout.Container) {
+ HierachyViewerComponent.containerManager = container;
+ }
- console.log('Hierachy state saved.');
- }
+ public onInput(e: Event): void {
+ this.container.extendState({
+ value: (e.target).value
+ });
- public glOnResize(): void {
- console.log('Hierachy Resizing!');
- }
+ console.log('Hierachy state saved.');
+ }
- public glOnShow(): void {
- console.log('Hierachy Showing!');
- }
+ public glOnResize(): void {
+ }
- public glOnHide(): void {
- console.log('Hierachy Hiding!');
- }
+ public glOnShow(): void {
+ console.log('Hierachy Showing!');
+ }
- /*public glOnTab(): void {
- console.log('Tab shown!');
- }*/
+ public glOnHide(): void {
+ console.log('Hierachy Hiding!');
+ }
+
+ public ngOnInit() {
+ }
+
+ public ngOnDestroy() {
+ var stop = 0;
+ }
}
\ No newline at end of file
diff --git a/Editor/src/app/MenuBar/menuBar.component.ts b/Editor/src/app/MenuBar/menuBar.component.ts
index 2e034d7..852d1cb 100644
--- a/Editor/src/app/MenuBar/menuBar.component.ts
+++ b/Editor/src/app/MenuBar/menuBar.component.ts
@@ -1,89 +1,356 @@
import { Component, OnInit, ViewChild } from '@angular/core';
import { MatMenuTrigger } from '@angular/material/menu';
-
+import { ConsoleViewerComponent } from '../ConsoleViewer/consoleViewer.component';
+import { HierachyViewerComponent } from '../HierachyViewer/hierachyViewer.component';
+import { PropertiesViewerComponent } from '../PropertiesViewer/propertiesViewer.component';
+import { SceneViewerComponent } from '../SceneViewer/sceneViewer.component';
+import { ProjectViewerComponent } from '../ProjectViewer/projectViewer.component';
+
+import {
+ GoldenLayoutModule,
+ GoldenLayoutConfiguration,
+ GoldenLayoutService,
+ GoldenLayoutContainer
+ } from 'ng-golden-layout';
+ import * as GoldenLayout from 'golden-layout';
+
@Component({
- selector: 'menu-bar',
- templateUrl: './menuBar.html',
- styleUrls: ['./menuBar.css'],
+ selector: 'menu-bar',
+ templateUrl: './menuBar.html',
+ styleUrls: ['./menuBar.scss']
})
+
+
export class MenuBarComponent {
// File dropdown options:
- gFileOptions: Array
+
+
+
+
+
\ No newline at end of file
diff --git a/Editor/src/app/MenuBar/menuBar.css b/Editor/src/app/MenuBar/menuBar.scss
similarity index 77%
rename from Editor/src/app/MenuBar/menuBar.css
rename to Editor/src/app/MenuBar/menuBar.scss
index 28ca89d..3c48b23 100644
--- a/Editor/src/app/MenuBar/menuBar.css
+++ b/Editor/src/app/MenuBar/menuBar.scss
@@ -4,7 +4,9 @@
.mainMenuToolBar .mat-toolbar.mat-toolbar-single-row {
height: 10%;
padding: 0px 0px 0px 0px;
+ color: whitesmoke;
}
+
.mainMenuToolBar button#file.mat-button {
font-size: 15px;
padding: 0px 10px 0px 10px;
@@ -17,6 +19,12 @@
min-width: 15px;
}
+.mainMenuToolBar button#view.mat-button {
+ font-size: 15px;
+ padding: 0px 10px 0px 10px;
+ min-width: 15px;
+}
+
/* Menu Bar dropdown button styling */
.menuBarItem {
line-height: 18px;
diff --git a/Editor/src/app/ProjectViewer/projectViewer.component.ts b/Editor/src/app/ProjectViewer/projectViewer.component.ts
index 5e93a10..f766aac 100644
--- a/Editor/src/app/ProjectViewer/projectViewer.component.ts
+++ b/Editor/src/app/ProjectViewer/projectViewer.component.ts
@@ -12,8 +12,12 @@ import * as GoldenLayout from 'golden-layout';
})
export class ProjectViewerComponent implements GlOnResize, GlOnHide, GlOnShow {
+ public static containerManager : GoldenLayout.Container;
+
constructor(@Inject(GoldenLayoutComponentState) private state: any,
- @Inject(GoldenLayoutContainer) private container: GoldenLayout.Container) {}
+ @Inject(GoldenLayoutContainer) private container: GoldenLayout.Container) {
+ ProjectViewerComponent.containerManager = container;
+ }
public onInput(e: Event): void {
diff --git a/Editor/src/app/PropertiesViewer/VMLayer/propertiesViewerVM.service.ts b/Editor/src/app/PropertiesViewer/VMLayer/propertiesViewerVM.service.ts
new file mode 100644
index 0000000..fb2c7f3
--- /dev/null
+++ b/Editor/src/app/PropertiesViewer/VMLayer/propertiesViewerVM.service.ts
@@ -0,0 +1,254 @@
+import { Component, Injectable, Injector, ReflectiveInjector } from '@angular/core';
+import { PropertiesViewerService } from '../propertiesViewer.service';
+import { PropertyLabels } from '../Properties/propertyLabels';
+import { Vector3Viewer } from '../Properties/vec3Viewer/vec3Viewer.component';
+import { Vector2Viewer } from '../Properties/vec2Viewer/vec2Viewer.component';
+import { BoolViewer } from '../Properties/boolViewer/boolViewer.component';
+import { StringViewer } from '../Properties/stringViewer/stringViewer.component';
+import { SliderViewer } from '../Properties/sliderViewer/sliderViewer.component';
+import { UndoRedoManagerService, UndoRedoAction } from '../../../assets/Utils/UndoRedo/UndoRedoManager.service';
+
+export class propertyData {
+ type: Object;
+ injector: Injector;
+}
+
+export class property {
+ name: string;
+ propertiesData: Array;
+ constructor() {
+ this.propertiesData = new Array();
+ }
+}
+
+
+@Injectable()
+export class PropertiesViewerVMService {
+ private componentTypes : Map;
+ private undoRedoService : UndoRedoManagerService;
+ private componentsList : Array;
+ private gameObjectProperties : Array;
+
+ constructor(private propertiesViewerService: PropertiesViewerService,
+ private injector: Injector,
+ private undoRedoManagerService: UndoRedoManagerService) {
+
+
+ this.undoRedoService = UndoRedoManagerService.getInstance();
+ this.componentTypes = new Map();
+ this.componentsList = Array();
+ this.gameObjectProperties = Array();
+ this.getGameComponentsStructures();
+ }
+
+ // public methods:
+ public addComponent(componentName: string) {
+ var property = this.addComponentToPropertyViewer(componentName);
+ this.UndoRedoAddComponent(componentName);
+ }
+
+ public removeComponent(componentName: string) {
+ this.UndoRedoRemoveComponent(componentName);
+ this.removeComponentFromPropertyViewer(componentName);
+ }
+
+ public undoEventTrigger() {
+ this.undoRedoManagerService.Undo();
+ }
+
+ public redoEventTrigger() {
+ this.undoRedoManagerService.Redo();
+ }
+
+
+ public getComponentsList() : Array {
+ return this.componentsList;
+ }
+
+ public getGameObjectProperties() : Array {
+ return this.gameObjectProperties;
+ }
+
+
+ // private methods:
+ private addComponentToPropertyViewer = (componentName: string) => {
+ var componentStructure = this.componentTypes[componentName];
+ if(Array.isArray(componentName)) {
+ componentStructure = this.componentTypes[componentName['0']];
+ }
+ else {
+ componentStructure = this.componentTypes[componentName];
+ }
+ var componentProperty = new property();
+
+ componentProperty.name = componentName;
+ //Scale, Rotate, Translate
+ for(let member of componentStructure) {
+ let componentData = new propertyData();
+ switch(member.typeName) {
+ case "vec3":{
+ this.addVec3SubProperty(member, componentProperty, componentData);
+ break;
+ }
+ case "vec2": {
+ this.addVec2SubProperty(member, componentProperty, componentData)
+ break;
+ }
+ case "bool": {
+ this.addBoolSubProperty(member, componentProperty, componentData);
+ break;
+ }
+ case "string": {
+ this.addStringSubProperty(member, componentProperty, componentData);
+ break;
+ }
+ case "float": {
+ this.addSliderSubProperty(member, componentProperty, componentData);
+ break;
+ }
+ }
+ }
+ this.gameObjectProperties.push(componentProperty);
+ }
+
+ public removeComponentFromPropertyViewer = (componentName : string) => {
+ // this function is either going to get passed the components name as a string.
+ // or the undo/redo is going to pass it an array with 1 element in it.
+ var realComponentName;
+ if(Array.isArray(componentName)) {
+ realComponentName = componentName['0'];
+ }
+ else {
+ realComponentName = componentName;
+ }
+
+ // remove the component from the properties viewer
+ for(var i = 0; i < this.gameObjectProperties.length; ++i) {
+ if(this.gameObjectProperties[i].name == realComponentName) {
+ this.gameObjectProperties.splice(i, 1);
+ }
+ }
+ }
+
+
+ // Gets the structural mark up for all the component types
+ private getGameComponentsStructures() {
+ this.propertiesViewerService.getComponentsStructures().subscribe(gameComponentStructures => {
+ var components = gameComponentStructures['Components'];
+ for(var i = 0; i < components.length; ++i){
+ // add the component name to the components list
+ var componentName = components[i]['typeName'];
+ this.componentsList.push(componentName);
+ this.componentTypes[componentName] = components[i]['members'];
+ }
+ }
+ );
+ }
+
+
+ // Gets a list of all existing component types
+ private getComponentTypes() {
+ this.propertiesViewerService.getComponentsList().subscribe(componentTypes => {
+
+ }
+ );
+ }
+
+ private addVec3SubProperty(vec3: any, vec3Property:property, vec3Data: propertyData) {
+ let vec3Labels = new Array(3);
+
+ for(let i = 0; i < vec3.members.length; ++i) {
+ vec3Labels[i] = vec3.members[i].name;
+ }
+
+ let componentInjector = ReflectiveInjector.resolveAndCreate([{
+ provide: PropertyLabels,
+ useValue: {
+ 'name' : vec3.name,
+ 'xLabel': vec3Labels[0],
+ 'yLabel': vec3Labels[1],
+ 'zLabel': vec3Labels[2]
+ }
+ }], this.injector)
+
+ vec3Data.injector = componentInjector;
+ vec3Data.type = Vector3Viewer;
+ vec3Property.propertiesData.push(vec3Data);
+ }
+
+ private addVec2SubProperty(vec2: any, vec2Property, vec2Data: propertyData) {
+ let vec2Labels = new Array(2);
+
+ let i = 0;
+ for(let i = 0; i < vec2.members.length; ++i) {
+ vec2Labels[i] = vec2.members[i].name;
+ }
+
+ let componentInjector = ReflectiveInjector.resolveAndCreate([{
+ provide: PropertyLabels,
+ useValue: {
+ 'name' : vec2.name,
+ 'xLabel': vec2Labels[0],
+ 'yLabel': vec2Labels[1]
+ }
+ }], this.injector)
+
+ vec2Data.injector = componentInjector;
+ vec2Data.type = Vector2Viewer;
+ vec2Property.propertiesData.push(vec2Data);
+ }
+
+ private addBoolSubProperty(boolean: any, boolProperty: property, boolData: propertyData) {
+ let componentInjector = ReflectiveInjector.resolveAndCreate([{
+ provide: PropertyLabels,
+ useValue: {
+ 'name' : boolean.name,
+ }
+ }], this.injector);
+
+ boolData.injector = componentInjector;
+ boolData.type = BoolViewer;
+ boolProperty.propertiesData.push(boolData);
+ }
+
+ private addStringSubProperty(str: any, stringProperty: property, stringData: propertyData) {
+ let componentInjector = ReflectiveInjector.resolveAndCreate([{
+ provide: PropertyLabels,
+ useValue: {
+ 'name' : str.name,
+ }
+ }], this.injector);
+
+ stringData.injector = componentInjector;
+ stringData.type = StringViewer;
+ stringProperty.propertiesData.push(stringData);
+ }
+
+ private addSliderSubProperty(slider: any, sliderProperty: property, sliderData: propertyData): void {
+ let componentInjector = ReflectiveInjector.resolveAndCreate([{
+ provide: PropertyLabels,
+ useValue: {
+ 'name' : slider.name,
+ }
+ }], this.injector);
+
+ sliderData.injector = componentInjector;
+ sliderData.type = SliderViewer;
+ sliderProperty.propertiesData.push(sliderData);
+ }
+
+ // Undo // Redo features
+ private UndoRedoAddComponent (componentName : string) {
+ var addComponentActions = new UndoRedoAction();
+ addComponentActions.setExecuteFunc(this.addComponentToPropertyViewer, componentName);
+ addComponentActions.setUnexecuteFunc(this.removeComponentFromPropertyViewer, componentName);
+ this.undoRedoService.Add(addComponentActions);
+ }
+
+ private UndoRedoRemoveComponent(componentName : string) {
+ var removeComponentActions = new UndoRedoAction();
+ removeComponentActions.setExecuteFunc(this.removeComponentFromPropertyViewer, componentName);
+ removeComponentActions.setUnexecuteFunc(this.addComponentToPropertyViewer, componentName);
+ this.undoRedoService.Add(removeComponentActions);
+ }
+};
\ No newline at end of file
diff --git a/Editor/src/app/PropertiesViewer/propertiesViewer.component.ts b/Editor/src/app/PropertiesViewer/propertiesViewer.component.ts
index f391587..5165e0a 100644
--- a/Editor/src/app/PropertiesViewer/propertiesViewer.component.ts
+++ b/Editor/src/app/PropertiesViewer/propertiesViewer.component.ts
@@ -7,206 +7,65 @@ import { Vector2Viewer } from './Properties/vec2Viewer/vec2Viewer.component';
import { BoolViewer } from './Properties/boolViewer/boolViewer.component';
import { StringViewer } from './Properties/stringViewer/stringViewer.component';
import { SliderViewer } from './Properties/sliderViewer/sliderViewer.component';
+import { PropertiesViewerVMService, property } from './VMLayer/propertiesViewerVM.service';
import * as GoldenLayout from 'golden-layout';
-class propertyData {
- type: Object;
- injector: Injector;
-}
-
-class property {
- name: string;
- propertiesData: Array;
- constructor() {
- this.propertiesData = new Array();
- }
-}
-
@Component({
- selector: 'properties-viewer',
- templateUrl: './propertiesViewer.html',
- styleUrls: ['./propertiesViewer.scss']
+ selector: 'properties-viewer',
+ templateUrl: './propertiesViewer.html',
+ styleUrls: ['./propertiesViewer.css']
})
export class PropertiesViewerComponent implements GlOnResize, GlOnHide, GlOnShow {
- //List of components queried from the engine
- componentsList: Object;
- gameObjectComponents: Object;
-
- //Array of properties currently to be viewed
- currentGameObjectProperties: Array;
-
- constructor(@Inject(GoldenLayoutComponentState) private state: any,
- @Inject(GoldenLayoutContainer) private container: GoldenLayout.Container,
- private service: PropertiesViewerService,
- private injector: Injector) {
- this.currentGameObjectProperties = new Array();
- }
+ public static containerManager : GoldenLayout.Container;
- ngOnInit() {
- this.getGameObjectComponents();
- this.getAllComponents();
- }
-
- //Gets all components on a game object
- getGameObjectComponents() {
- this.service.getGameObjectComponents().subscribe(gameObjectComponents => {
- this.gameObjectComponents = gameObjectComponents;
- });
- }
+ constructor(@Inject(GoldenLayoutComponentState) private state: any,
+ @Inject(GoldenLayoutContainer) private container: GoldenLayout.Container,
+ private propertiesViewerVMService: PropertiesViewerVMService) {
+
+ PropertiesViewerComponent.containerManager = container;
+ }
- //Gets all existing components from the game engine
- getAllComponents() {
- this.service.getComponents().subscribe(components => {
- this.componentsList = components;
- });
- }
+ getComponentsList() : Array {
+ return this.propertiesViewerVMService.getComponentsList();
+ }
+ getGameObjectProperties() : Array {
+ return this.propertiesViewerVMService.getGameObjectProperties();
+ }
- addComponent(componentName: string) {
-
- let component = this.componentsList['Components'];
- let componentProperty = new property();
- for(let property of component) {
- //Transform, Sprite,...
- if(property.typeName == componentName){
- componentProperty.name = componentName;
- //Scale, Rotate, Translate
- for(let member of property.members) {
- let componentData = new propertyData();
- switch(member.typeName) {
- case "vec3":{
- this.addVec3SubProperty(member, componentProperty, componentData);
- break;
- }
- case "vec2": {
- this.addVec2SubProperty(member, componentProperty, componentData)
- break;
- }
- case "bool": {
- this.addBoolSubProperty(member, componentProperty, componentData);
- break;
- }
- case "string": {
- this.addStringSubProperty(member, componentProperty, componentData);
- break;
- }
- case "float": {
- this.addSliderSubProperty(member, componentProperty, componentData);
- break;
- }
- }
- }
- this.currentGameObjectProperties.push(componentProperty);
- return;
- }
+ addComponent(componentName: string) {
+ var componentProperty = this.propertiesViewerVMService.addComponent(componentName);
}
- }
-
-
- addVec3SubProperty(vec3: any, vec3Property:property, vec3Data: propertyData) {
- let vec3Labels = new Array(3);
- for(let i = 0; i < vec3.members.length; ++i) {
- vec3Labels[i] = vec3.members[i].name;
+ removeComponent(componentName:string) {
+ this.propertiesViewerVMService.removeComponent(componentName);
}
+
+ public onInput(e: Event): void {
+ this.container.extendState({
+ value: (e.target).value
+ });
- let componentInjector = ReflectiveInjector.resolveAndCreate([{
- provide: PropertyLabels,
- useValue: {
- 'name' : vec3.name,
- 'xLabel': vec3Labels[0],
- 'yLabel': vec3Labels[1],
- 'zLabel': vec3Labels[2]
- }
- }], this.injector)
-
- vec3Data.injector = componentInjector;
- vec3Data.type = Vector3Viewer;
- vec3Property.propertiesData.push(vec3Data);
- }
-
- addVec2SubProperty(vec2: any, vec2Property, vec2Data: propertyData) {
- let vec2Labels = new Array(2);
-
- let i = 0;
- for(let i = 0; i < vec2.members.length; ++i) {
- vec2Labels[i] = vec2.members[i].name;
+ console.log('Game Object Properties state saved.');
}
- let componentInjector = ReflectiveInjector.resolveAndCreate([{
- provide: PropertyLabels,
- useValue: {
- 'name' : vec2.name,
- 'xLabel': vec2Labels[0],
- 'yLabel': vec2Labels[1]
- }
- }], this.injector)
-
- vec2Data.injector = componentInjector;
- vec2Data.type = Vector2Viewer;
- vec2Property.propertiesData.push(vec2Data);
- }
-
- addBoolSubProperty(boolean: any, boolProperty: property, boolData: propertyData) {
- let componentInjector = ReflectiveInjector.resolveAndCreate([{
- provide: PropertyLabels,
- useValue: {
- 'name' : boolean.name,
- }
- }], this.injector);
-
- boolData.injector = componentInjector;
- boolData.type = BoolViewer;
- boolProperty.propertiesData.push(boolData);
- }
-
- addStringSubProperty(str: any, stringProperty: property, stringData: propertyData) {
- let componentInjector = ReflectiveInjector.resolveAndCreate([{
- provide: PropertyLabels,
- useValue: {
- 'name' : str.name,
- }
- }], this.injector);
-
- stringData.injector = componentInjector;
- stringData.type = StringViewer;
- stringProperty.propertiesData.push(stringData);
- }
-
- addSliderSubProperty(slider: any, sliderProperty: property, sliderData: propertyData): void {
- let componentInjector = ReflectiveInjector.resolveAndCreate([{
- provide: PropertyLabels,
- useValue: {
- 'name' : slider.name,
- }
- }], this.injector);
-
- sliderData.injector = componentInjector;
- sliderData.type = SliderViewer;
- sliderProperty.propertiesData.push(sliderData);
- }
-
- public onInput(e: Event): void {
-
- this.container.extendState({
- value: (e.target).value
- });
-
- console.log('Game Object Properties state saved.');
- }
+ public glOnResize(): void {
+ console.log('Game Object Properties Resizing!');
+ }
- public glOnResize(): void {
- console.log('Game Object Properties Resizing!');
- }
+ public glOnShow(): void {
+ console.log('Game Object Properties Showing!');
+ }
- public glOnShow(): void {
- console.log('Game Object Properties Showing!');
- }
+ public glOnHide(): void {
+ console.log('Game Object Properties Hiding!');
+ }
- public glOnHide(): void {
- console.log('Game Object Properties Hiding!');
- }
+ public ngOnInit() {
+ }
+ public ngOnDestroy() {
+ }
}
\ No newline at end of file
diff --git a/Editor/src/app/PropertiesViewer/propertiesViewer.css b/Editor/src/app/PropertiesViewer/propertiesViewer.css
new file mode 100644
index 0000000..a757b18
--- /dev/null
+++ b/Editor/src/app/PropertiesViewer/propertiesViewer.css
@@ -0,0 +1,10 @@
+.propertiesBtn {
+ text-align: center;
+}
+
+#propertiesView .mat-expansion-panel button.mat-button{
+ width: 16px;
+ padding: 0px;
+ min-width: 30px;
+ line-height: 15px;
+}
diff --git a/Editor/src/app/PropertiesViewer/propertiesViewer.html b/Editor/src/app/PropertiesViewer/propertiesViewer.html
index e508889..598db88 100644
--- a/Editor/src/app/PropertiesViewer/propertiesViewer.html
+++ b/Editor/src/app/PropertiesViewer/propertiesViewer.html
@@ -1,24 +1,27 @@
-
-
-
- {{property.name}}
-
-
-
-
-
+
+
+
+
+
+ {{property.name}}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
diff --git a/Editor/src/app/PropertiesViewer/propertiesViewer.scss b/Editor/src/app/PropertiesViewer/propertiesViewer.scss
deleted file mode 100644
index 6f79a6f..0000000
--- a/Editor/src/app/PropertiesViewer/propertiesViewer.scss
+++ /dev/null
@@ -1,3 +0,0 @@
-.propertiesBtn {
- text-align: center;
-}
\ No newline at end of file
diff --git a/Editor/src/app/PropertiesViewer/propertiesViewer.service.ts b/Editor/src/app/PropertiesViewer/propertiesViewer.service.ts
index 9c752bf..f05a920 100644
--- a/Editor/src/app/PropertiesViewer/propertiesViewer.service.ts
+++ b/Editor/src/app/PropertiesViewer/propertiesViewer.service.ts
@@ -7,35 +7,28 @@ import { catchError, map, tap } from 'rxjs/operators';
@Injectable()
export class PropertiesViewerService {
private engineUrl = '../../assets';
+ private realEngineURL = 'http://localhost:42069/api'
- constructor(
- private http: HttpClient) {}
+ constructor(private http: HttpClient) {}
+
+ getComponentsList() {
+ const url = `${this.realEngineURL}/ComponentsList`;
+ return this.http.get(url);
+ }
+
+ getComponentsStructures() {
+ const url = `${this.realEngineURL}/Components`;
+ return this.http.get(url);
+ }
getComponents() {
const url = `${this.engineUrl}/components.json`;
- return this.http.get(url).pipe(
- tap(component => console.log('fetching all components')),
- catchError(this.handleError('getComponents', []))
- );
+ return this.http.get(url);
}
getGameObjectComponents() {
const url = `${this.engineUrl}/propertiesData.json`;
- return this.http.get(url).pipe(
- tap(component => console.log('fetching gameobject components')),
- catchError(this.handleError('getGameObjectComponents', []))
- );
- }
-
- private handleError
(operation = 'operation', result?: T) {
- return (error: any): Observable => {
-
- //TODO: find a better way to display/log errors
- console.error(error);
-
- // Let the app keep running by returning an empty result.
- return of(result as T);
- };
+ return this.http.get(url);
}
}
\ No newline at end of file
diff --git a/Editor/src/app/SceneViewer/sceneViewer.component.ts b/Editor/src/app/SceneViewer/sceneViewer.component.ts
index 0960dd4..68b873d 100644
--- a/Editor/src/app/SceneViewer/sceneViewer.component.ts
+++ b/Editor/src/app/SceneViewer/sceneViewer.component.ts
@@ -13,8 +13,12 @@ export class SceneViewerComponent implements GlOnResize {
@ViewChild('editorView') editorView: ElementRef
+ public static containerManager : GoldenLayout.Container;
+
constructor(@Inject(GoldenLayoutComponentState) private state: any,
- @Inject(GoldenLayoutContainer) private container: GoldenLayout.Container) {}
+ @Inject(GoldenLayoutContainer) private container: GoldenLayout.Container) {
+ SceneViewerComponent.containerManager = container;
+ }
canvas : HTMLCanvasElement;
gl: WebGL2RenderingContext;
diff --git a/Editor/src/app/app.component.ts b/Editor/src/app/app.component.ts
index 84b9bfc..da14145 100644
--- a/Editor/src/app/app.component.ts
+++ b/Editor/src/app/app.component.ts
@@ -1,17 +1,54 @@
import { Component, OnInit } from '@angular/core';
-import { MenuBarComponent } from './MenuBar/menuBar.component';
+import { UndoRedoManagerService } from '../assets/Utils/UndoRedo/UndoRedoManager.service';
+import { ConsoleViewerComponent } from './ConsoleViewer/consoleViewer.component';
+
@Component({
- selector: 'editor',
- template: `
-
-
-
-
- `,
- //templateUrl: './app.component.html',
- styleUrls: ['./app.component.css']
+ selector: 'editor',
+ template: `
+
+
+
+
+ `,
+ //templateUrl: './app.component.html',
+ styleUrls: ['./app.component.css']
})
+
export class AppComponent {
- //title = 'app';
+ undoRedoManager : UndoRedoManagerService;
+
+ constructor() {
+ this.undoRedoManager = UndoRedoManagerService.getInstance();
+ }
+
+
+ ngOnInit() {
+ this.LoadEventListeners();
+ }
+
+
+ private LoadEventListeners() {
+ document.addEventListener('keydown', (event) => {
+ const keyName = event.key;
+ if(keyName === 'Control') {
+ return;
+ }
+
+ if(event.ctrlKey) {
+ // undo, Ctrl+Z
+ if(event.keyCode == 90) {
+ this.undoRedoManager.Undo();
+ return;
+ }
+
+ // redo, Ctrl+Y
+ if(event.keyCode == 89) {
+ this.undoRedoManager.Redo();
+ return;
+ }
+ }
+ })
+ }
}
+
diff --git a/Editor/src/app/app.module.ts b/Editor/src/app/app.module.ts
index 01133b4..bf235fd 100644
--- a/Editor/src/app/app.module.ts
+++ b/Editor/src/app/app.module.ts
@@ -25,12 +25,15 @@ import { ProjectViewerComponent } from './ProjectViewer/projectViewer.component'
import { HierachyViewerComponent } from './HierachyViewer/hierachyViewer.component';
import { PropertiesViewerComponent } from './PropertiesViewer/propertiesViewer.component';
import { PropertiesViewerService } from './PropertiesViewer/propertiesViewer.service';
+import { PropertiesViewerVMService } from './PropertiesViewer/VMLayer/propertiesViewerVM.service';
+import { UndoRedoManagerService } from '../assets/Utils/UndoRedo/UndoRedoManager.service';
import { PropertyLabels } from './PropertiesViewer/Properties/propertyLabels';
import { StringViewer } from './PropertiesViewer/Properties/stringViewer/stringViewer.component';
import { SliderViewer } from './PropertiesViewer/Properties/sliderViewer/sliderViewer.component';
import { Vector3Viewer } from './PropertiesViewer/Properties/vec3Viewer/vec3Viewer.component';
import { Vector2Viewer } from './PropertiesViewer/Properties/vec2Viewer/vec2Viewer.component';
import { BoolViewer } from './PropertiesViewer/Properties/boolViewer/boolViewer.component';
+import { ConsoleViewerComponent } from './ConsoleViewer/consoleViewer.component';
import 'hammerjs';
@@ -43,6 +46,7 @@ import * as GoldenLayout from 'golden-layout';
import * as Jquery from 'jquery';
import { AppComponent } from './app.component';
+
const goldenLayoutConfig: GoldenLayoutConfiguration = {
components: [
{
@@ -63,24 +67,29 @@ const goldenLayoutConfig: GoldenLayoutConfiguration = {
},
{
component: HierachyViewerComponent,
- componentName: 'Hierachy'
+ componentName: 'Hierarchy'
+ },
+ {
+ component: ConsoleViewerComponent,
+ componentName: 'Console'
}
],
-
+
defaultLayout: {
- settings:{
- // hasHeaders: true,
+ settings: {
+ // hasHeaders: false
},
dimensions: {
- minItemHeight: 300,
- minItemWidth: 300,
+ minItemHeight: 200,
+ minItemWidth: 200,
+ borderWidth: 3
},
content: [
{
- type: 'row',
+ type: 'column',
content: [
{
- type: 'column',
+ type: 'row',
content: [
{
type: 'row',
@@ -88,41 +97,53 @@ const goldenLayoutConfig: GoldenLayoutConfiguration = {
{//Hierarchy View
type: 'component',
width: 20,
- componentName: 'Hierachy',
+ height: 20,
+ componentName: 'Hierarchy',
},
{//Editor/Game View
type: 'stack',
content: [
{
- type: 'component',
+ type: 'component',
+ width: 20,
+ height: 20,
componentName: 'Scene',
componentState: {
text: "Editor Window Here"
},
- isClosable: false
},
{
type: 'component',
+ width: 20,
+ height: 20,
componentName: 'test-panel',
componentState: {
text: 'Game Window Here'
},
isClosable: false
}]
+ },
+ {//Game Component View
+ type: 'component',
+ width: 20,
+ height: 20,
+ componentName: 'Properties',
}]
- },
- {//Project File View
- type: 'component',
- height: 20,
- componentName: 'Project',
}]
},
- {//Game Component View
+ {//Project File View
type: 'component',
width: 20,
- componentName: 'Properties',
- isClosable: false
- }]
+ height: 20,
+ componentName: 'Project',
+ },
+ {//Project File View
+ type: 'component',
+ width: 0,
+ height: 0,
+ componentName: 'Console',
+ },
+ ]
}]
}
}
@@ -135,6 +156,7 @@ const goldenLayoutConfig: GoldenLayoutConfiguration = {
ProjectViewerComponent,
HierachyViewerComponent,
PropertiesViewerComponent,
+ ConsoleViewerComponent,
MenuBarComponent,
ContextMenuComponent,
Vector3Viewer,
@@ -151,6 +173,7 @@ const goldenLayoutConfig: GoldenLayoutConfiguration = {
HierachyViewerComponent,
MenuBarComponent,
PropertiesViewerComponent,
+ ConsoleViewerComponent,
Vector3Viewer,
Vector2Viewer,
SliderViewer,
@@ -177,8 +200,12 @@ const goldenLayoutConfig: GoldenLayoutConfiguration = {
providers: [
// DEFAULT_LOCAL_STORAGE_STATE_STORE_PROVIDER
PropertiesViewerService,
+ PropertiesViewerVMService,
+ UndoRedoManagerService,
PropertyLabels
],
bootstrap: [AppComponent]
})
-export class AppModule { }
+
+export class AppModule {
+}
diff --git a/Editor/src/assets/Utils/UndoRedo/UndoRedoManager.service.ts b/Editor/src/assets/Utils/UndoRedo/UndoRedoManager.service.ts
new file mode 100644
index 0000000..09a735e
--- /dev/null
+++ b/Editor/src/assets/Utils/UndoRedo/UndoRedoManager.service.ts
@@ -0,0 +1,86 @@
+import {Injectable} from '@angular/core';
+//import { exec } from 'child_process';
+
+interface UndoInterface {
+ Execute();
+ UnExecute();
+}
+
+export class UndoRedoAction implements UndoInterface {
+ mExecuteTask : Function;
+ mUnexecuteTask : Function;
+ mExecuteTaskParams : Array;
+ mUnexecuteTaskParams : Array;
+
+ constructor() {
+ }
+
+ public setExecuteFunc(executeTask : Function, ...args: any[]) {
+ this.mExecuteTask = executeTask;
+ this.mExecuteTaskParams = args;
+ }
+
+ public setUnexecuteFunc(unexecuteTask : Function, ...args: any[]) {
+ this.mUnexecuteTask = unexecuteTask;
+ this.mUnexecuteTaskParams = args;
+ }
+
+ public Execute() {
+ if(this.mExecuteTaskParams.length != 0) {
+ this.mExecuteTask(this.mExecuteTaskParams);
+ }
+ else {
+ this.mExecuteTask();
+ }
+ }
+
+ public UnExecute() {
+ if(this.mUnexecuteTaskParams.length != 0) {
+ this.mUnexecuteTask(this.mUnexecuteTaskParams);
+ }
+ else {
+ this.mUnexecuteTask();
+ }
+ }
+}
+
+
+@Injectable()
+export class UndoRedoManagerService {
+ private static instance: UndoRedoManagerService;
+ private redoStack : Array;
+ private undoStack : Array;
+
+ constructor() {
+ this.redoStack = Array();
+ this.undoStack = Array();
+ }
+
+ static getInstance() {
+ if (!UndoRedoManagerService.instance) {
+ UndoRedoManagerService.instance = new UndoRedoManagerService();
+ }
+ return UndoRedoManagerService.instance;
+ }
+
+ public Undo() {
+ if(this.undoStack.length != 0) {
+ var undoTask = this.undoStack[this.undoStack.length - 1];
+ undoTask.UnExecute();
+ this.undoStack.pop();
+ this.redoStack.push(undoTask);
+ }
+ }
+ public Redo() {
+ if(this.redoStack.length != 0) {
+ var redoTask = this.redoStack[this.redoStack.length - 1];
+ redoTask.Execute();
+ this.redoStack.pop();
+ this.undoStack.push(redoTask);
+ }
+ }
+
+ public Add(action : UndoRedoAction) {
+ this.undoStack.push(action);
+ }
+};
\ No newline at end of file
diff --git a/Editor/src/index.html b/Editor/src/index.html
index 0e1bc0c..a43d8c5 100644
--- a/Editor/src/index.html
+++ b/Editor/src/index.html
@@ -5,6 +5,7 @@
+
diff --git a/pilcrow/engine/rest_api/include/RESTAPI.h b/pilcrow/engine/rest_api/include/RESTAPI.h
index 733951b..844e54a 100644
--- a/pilcrow/engine/rest_api/include/RESTAPI.h
+++ b/pilcrow/engine/rest_api/include/RESTAPI.h
@@ -2,6 +2,7 @@
#include
#include
+#include
class Simulation;
class Entity;
@@ -37,8 +38,12 @@ class REST_VM
private:
void handle_request(web::http::http_request message);
void handle_error(pplx::task& t);
+ web::json::value GetComponentsList();
+
+
web::http::experimental::listener::http_listener m_listener;
Simulation &m_simulation;
+ std::map> mRoutesMap;
};
diff --git a/pilcrow/engine/rest_api/src/RESTAPI.cpp b/pilcrow/engine/rest_api/src/RESTAPI.cpp
index b4c495b..64eeb14 100644
--- a/pilcrow/engine/rest_api/src/RESTAPI.cpp
+++ b/pilcrow/engine/rest_api/src/RESTAPI.cpp
@@ -17,16 +17,20 @@
+
REST_VM::REST_VM(Simulation &sim, utility::string_t url)
: m_listener(url)
, m_simulation(sim) {
m_listener.support(std::bind(&REST_VM::handle_request, this, std::placeholders::_1));
+ mRoutesMap[U("Components")] = std::bind(&REST_VM::GetComponentsList, this);
}
+
REST_VM::~REST_VM()
{
//dtor
}
+
void REST_VM::handle_error(pplx::task& t)
{
try
@@ -40,48 +44,116 @@ void REST_VM::handle_error(pplx::task& t)
}
}
+web::json::value REST_VM::GetComponentsList() {
+ web::json::value componentsList = web::json::value::object(true);
+ web::json::value components = web::json::value::array(1);
+ web::json::value transformObject = web::json::value::object(true);
+
+ transformObject[U("typeName")] = web::json::value::string(U("Transform"));
+ // position, rotation, scale
+ web::json::value transformMembers = web::json::value::array(3);
+
+ // Position member
+ web::json::value position = web::json::value::object(true);
+ position[U("name")] = web::json::value::string(U("Position"));
+ position[U("typeName")] = web::json::value::string(U("vec3"));
+
+ web::json::value positionMembers = web::json::value::array(3);
+
+ web::json::value positionMemberX = web::json::value::object(true);
+ positionMemberX[U("typeName")] = web::json::value::string(U("float"));
+ positionMemberX[U("name")] = web::json::value::string(U("X"));
+
+ web::json::value positionMemberY = web::json::value::object(true);
+ positionMemberY[U("typeName")] = web::json::value::string(U("float"));
+ positionMemberY[U("name")] = web::json::value::string(U("Y"));
+
+ web::json::value positionMemberZ = web::json::value::object(true);
+ positionMemberZ[U("typeName")] = web::json::value::string(U("float"));
+ positionMemberZ[U("name")] = web::json::value::string(U("Z"));
+
+ positionMembers[0] = positionMemberX;
+ positionMembers[1] = positionMemberY;
+ positionMembers[2] = positionMemberZ;
+ position[U("members")] = positionMembers;
+
+ // Rotation member
+ web::json::value rotation = web::json::value::object(true);
+ rotation[U("name")] = web::json::value::string(U("Rotation"));
+ rotation[U("typeName")] = web::json::value::string(U("vec3"));
+
+ web::json::value rotationMembers = web::json::value::array(3);
+
+ web::json::value rotationMemberX = web::json::value::object(true);
+ rotationMemberX[U("typeName")] = web::json::value::string(U("float"));
+ rotationMemberX[U("name")] = web::json::value::string(U("X"));
+
+ web::json::value rotationMemberY = web::json::value::object(true);
+ rotationMemberY[U("typeName")] = web::json::value::string(U("float"));
+ rotationMemberY[U("name")] = web::json::value::string(U("Y"));
+
+ web::json::value rotationMemberZ = web::json::value::object(true);
+ rotationMemberZ[U("typeName")] = web::json::value::string(U("float"));
+ rotationMemberZ[U("name")] = web::json::value::string(U("Z"));
+
+ rotationMembers[0] = rotationMemberX;
+ rotationMembers[1] = rotationMemberY;
+ rotationMembers[2] = rotationMemberZ;
+ rotation[U("members")] = rotationMembers;
+
+ // Scale memver
+ web::json::value scale = web::json::value::object(true);
+ scale[U("name")] = web::json::value::string(U("Scale"));
+ scale[U("typeName")] = web::json::value::string(U("vec3"));
+
+ web::json::value scaleMembers = web::json::value::array(3);
+
+ web::json::value scaleMemberX = web::json::value::object(true);
+ scaleMemberX[U("typeName")] = web::json::value::string(U("float"));
+ scaleMemberX[U("name")] = web::json::value::string(U("X"));
+
+ web::json::value scaleMemberY = web::json::value::object(true);
+ scaleMemberY[U("typeName")] = web::json::value::string(U("float"));
+ scaleMemberY[U("name")] = web::json::value::string(U("Y"));
+
+ web::json::value scaleMemberZ = web::json::value::object(true);
+ scaleMemberZ[U("typeName")] = web::json::value::string(U("float"));
+ scaleMemberZ[U("name")] = web::json::value::string(U("Z"));
+
+ scaleMembers[0] = scaleMemberX;
+ scaleMembers[1] = scaleMemberY;
+ scaleMembers[2] = scaleMemberZ;
+ scale[U("members")] = scaleMembers;
+
+
+ transformMembers[0] = position;
+ transformMembers[1] = rotation;
+ transformMembers[2] = scale;
+
+ transformObject[U("members")] = transformMembers;
+ components[0] = transformObject;
+ componentsList[U("Components")] = components;
+ return componentsList;
+}
+
+
void REST_VM::handle_request(web::http::http_request message)
{
using web::http::uri;
ucout << message.to_string() << std::endl;
auto paths = uri::split_path(uri::decode(message.relative_uri().path()));
-
- if (paths.empty()) message.reply(web::http::status_codes::BadRequest, "Empty Request.");
- else if (paths[0] == U("Worlds")) {
- std::string world_name;
- utility::string_t str;
- if (paths.size() > 1) {
- // @@TODO: this conversion isn't safe and should be updated in the future.
- world_name.assign(paths[1].begin(), paths[1].end());
- World &world{ m_simulation.GetWorld(world_name) };
- paths.erase(paths.begin(), paths.begin() + 2);
- if (paths.empty()) {
- // @@TODO: return contents of the world.
- message.reply(web::http::status_codes::OK, "The world \"" + world_name + "\" was found successfully.");
- }
- else if (paths[0] == U("Entities")) {
- if (paths.size() == 1) {
- //@@TODO: return list of all entities
-
- message.reply(web::http::status_codes::OK, "Retrieving all entities of of the world \"" + world_name + "\".");
- }
- else if (paths.size() > 1) {
- utility::istringstream_t iss(paths[1]);
- EntityID ID;
- iss >> ID.first;
- iss.get(); // pull out the comma
- iss >> ID.second;
- Entity *entity{ world.GetEntity(ID) };
- if (entity) {
- message.reply(web::http::status_codes::OK, U("The Entity with ID {") + paths[1] + U("} is named \"") + utility::string_t(entity->Name().begin(), entity->Name().end()) + U("\""));
- }
- else message.reply(web::http::status_codes::NotFound, "Entity requested does not exist.");
- }
- }
- }
+ auto path = message.relative_uri().path();
+ if (this->mRoutesMap.find(message.relative_uri().path()) != this->mRoutesMap.end()) {
+ web::json::value responseMessage = this->mRoutesMap[path]();
+ web::http::http_response response(web::http::status_codes::OK);
+ response.headers().add(U("Access-Control-Allow-Origin"), U("*"));
+ response.set_body(responseMessage);
+ message.reply(response);
}
- else message.reply(web::http::status_codes::InternalError, "That operation is not yet supported by the REST API.");
-
+ else {
+ message.reply(web::http::status_codes::InternalError, "That operation is not yet supported by the REST API.");
+ }
+ return;
}
diff --git a/pilcrow/runtimes/restful_runtime/src/main.cpp b/pilcrow/runtimes/restful_runtime/src/main.cpp
index 4332a44..4a95616 100644
--- a/pilcrow/runtimes/restful_runtime/src/main.cpp
+++ b/pilcrow/runtimes/restful_runtime/src/main.cpp
@@ -245,7 +245,7 @@ void ECSDemo() {
try {
- REST_VM h(Sim, utility::string_t(U("http://*:42069/api/")));
+ REST_VM h(Sim, utility::string_t(U("http://localhost:42069/api/")));
auto server = h.Open();
while (WindowOpen) {
double currentFrame = glfwGetTime();