From 42ccbbbc2fab06405377e112b28822e0f2a9ff65 Mon Sep 17 00:00:00 2001 From: Kyle Philistine Date: Fri, 20 Apr 2018 00:14:10 -0700 Subject: [PATCH 1/4] Properties Viewer VM Layer + moved most of the properties viewer logic to the VM layer + setup the properties viewer logic to call the VM layers + setup the RESTAPI in engine, the properties viewer is now getting info from the engine RESTAPI in engine + stubbed the transform component for front end testing / REST testing + reconstructed the RESTAPI to support localhost communication on chrome --- .../VMLayer/propertiesViewerVM.service.ts | 181 ++++++++++++++++++ .../propertiesViewer.component.ts | 147 +------------- .../PropertiesViewer/propertiesViewer.html | 6 +- .../propertiesViewer.service.ts | 35 ++-- Editor/src/app/app.module.ts | 2 + pilcrow/engine/rest_api/include/RESTAPI.h | 5 + pilcrow/engine/rest_api/src/RESTAPI.cpp | 144 ++++++++++---- pilcrow/runtimes/restful_runtime/src/main.cpp | 88 ++++----- 8 files changed, 365 insertions(+), 243 deletions(-) create mode 100644 Editor/src/app/PropertiesViewer/VMLayer/propertiesViewerVM.service.ts 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..0c5cc13 --- /dev/null +++ b/Editor/src/app/PropertiesViewer/VMLayer/propertiesViewerVM.service.ts @@ -0,0 +1,181 @@ +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'; + +class propertyData { + type: Object; + injector: Injector; +} + +class property { + name: string; + propertiesData: Array; + constructor() { + this.propertiesData = new Array(); + } +} + + +@Injectable() +export class PropertiesViewerVMService { + private componentTypes: Map; + public componentsList: Array; + + constructor(private propertiesViewerService: PropertiesViewerService, + private injector: Injector) { + + this.componentsList = Array(); + this.componentTypes = new Map(); + this.getGameComponentsStructures(); + } + + public addComponentToPropertyViewer(componentName: string) : property { + var 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; + } + } + } + return componentProperty; + } + + public getComponentsList() : Array { + return this.componentsList; + } + + + // 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); + } +}; \ 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..75d14a3 100644 --- a/Editor/src/app/PropertiesViewer/propertiesViewer.component.ts +++ b/Editor/src/app/PropertiesViewer/propertiesViewer.component.ts @@ -7,6 +7,8 @@ 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 } from './VMLayer/propertiesViewerVM.service'; + import * as GoldenLayout from 'golden-layout'; class propertyData { @@ -31,165 +33,34 @@ class property { export class PropertiesViewerComponent implements GlOnResize, GlOnHide, GlOnShow { //List of components queried from the engine - componentsList: Object; - gameObjectComponents: Object; + componentsList: Array; //Array of properties currently to be viewed currentGameObjectProperties: Array; constructor(@Inject(GoldenLayoutComponentState) private state: any, @Inject(GoldenLayoutContainer) private container: GoldenLayout.Container, + private propertiesViewerVMService: PropertiesViewerVMService, private service: PropertiesViewerService, private injector: Injector) { + this.currentGameObjectProperties = new Array(); } ngOnInit() { - this.getGameObjectComponents(); - this.getAllComponents(); - } - - //Gets all components on a game object - getGameObjectComponents() { - this.service.getGameObjectComponents().subscribe(gameObjectComponents => { - this.gameObjectComponents = gameObjectComponents; - }); } - //Gets all existing components from the game engine - getAllComponents() { - this.service.getComponents().subscribe(components => { - this.componentsList = components; - }); + getComponentsList() : Array { + return this.propertiesViewerVMService.getComponentsList(); } - 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; - } - } + var componentProperty = this.propertiesViewerVMService.addComponentToPropertyViewer(componentName); + this.currentGameObjectProperties.push(componentProperty); } - - 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); - } - - 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); - } - - 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 }); diff --git a/Editor/src/app/PropertiesViewer/propertiesViewer.html b/Editor/src/app/PropertiesViewer/propertiesViewer.html index e508889..41e4482 100644 --- a/Editor/src/app/PropertiesViewer/propertiesViewer.html +++ b/Editor/src/app/PropertiesViewer/propertiesViewer.html @@ -15,10 +15,8 @@ -
-
- -
+
+
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/app.module.ts b/Editor/src/app/app.module.ts index 01133b4..23e39f0 100644 --- a/Editor/src/app/app.module.ts +++ b/Editor/src/app/app.module.ts @@ -25,6 +25,7 @@ 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 { PropertyLabels } from './PropertiesViewer/Properties/propertyLabels'; import { StringViewer } from './PropertiesViewer/Properties/stringViewer/stringViewer.component'; import { SliderViewer } from './PropertiesViewer/Properties/sliderViewer/sliderViewer.component'; @@ -177,6 +178,7 @@ const goldenLayoutConfig: GoldenLayoutConfiguration = { providers: [ // DEFAULT_LOCAL_STORAGE_STATE_STORE_PROVIDER PropertiesViewerService, + PropertiesViewerVMService, PropertyLabels ], bootstrap: [AppComponent] 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 cc44106..c8845ef 100644 --- a/pilcrow/runtimes/restful_runtime/src/main.cpp +++ b/pilcrow/runtimes/restful_runtime/src/main.cpp @@ -162,49 +162,49 @@ void ECSDemo() { Simulation Sim; World &TestWorld{ Sim.CreateWorld("Test World") }; - //Load Global Game Settings - Always do this before adding systems! - SettingsFile settings{ "Settings.ini" }; - settings.Load(); - - TestWorld.AddSystem("Window Management System"); - //TestWorld.AddSystem("Gravity System"); - //TestWorld.AddSystem("Parallelized Gravity System", glm::vec3{ 0.f, -9.81f, 0.f }); - //TestWorld.AddSystem("Parallelized Velocity System"); - //TestWorld.AddSystem("Parallelized Acceleration System"); - TestWorld.AddSystem("Physics Integration"); - TestWorld.AddSystem("Physics Collision Detection"); - TestWorld.AddSystem("Physics Resolution"); - TestWorld.AddSystem("Rendering System"); - - - ArchetypeRef enemy{ Sim.CreateArchetype("Nanosuit Character") }; - ArchetypeRef lens{ Sim.CreateArchetype("Camera Lens") }; - lens.Add(); - enemy.Add().scale = { 0.2f, 0.2f, 0.2f }; - enemy.Get().position = { 0.0f, 0.0f, -3.0f }; - enemy.Get().rotation = { 0.f, 0.f, 0.f }; - enemy.Add(); - CModel& cm{ enemy.Add( "nanosuit.obj") }; - cm.model->Load(); - EntityRef cam{ TestWorld.Spawn(lens) }; - cam.Get().position = glm::vec3{ 4.5f, 3.4f, 14.26f }; - cam.Get().pitch = -11.f; - cam.Get().yaw = -89.f; - EntityRef EnemyA{ TestWorld.Spawn(enemy) }; - // set SpawnNanos to false if you want higher FPS and less nanosuits - std::vector nanos; - if (g_SpawnNanos) - { - std::vector nanos; - for (int i{ 0 }; i < 10; ++i) - { - for (int j{ 0 }; j < 10; ++j) - { - nanos.emplace_back(EnemyA.Clone()); - nanos.back().Get().position = glm::vec3{ i, 0, j }; - } - } - } + ////Load Global Game Settings - Always do this before adding systems! + //SettingsFile settings{ "Settings.ini" }; + //settings.Load(); + + //TestWorld.AddSystem("Window Management System"); + ////TestWorld.AddSystem("Gravity System"); + ////TestWorld.AddSystem("Parallelized Gravity System", glm::vec3{ 0.f, -9.81f, 0.f }); + ////TestWorld.AddSystem("Parallelized Velocity System"); + ////TestWorld.AddSystem("Parallelized Acceleration System"); + //TestWorld.AddSystem("Physics Integration"); + //TestWorld.AddSystem("Physics Collision Detection"); + //TestWorld.AddSystem("Physics Resolution"); + //TestWorld.AddSystem("Rendering System"); + + + //ArchetypeRef enemy{ Sim.CreateArchetype("Nanosuit Character") }; + //ArchetypeRef lens{ Sim.CreateArchetype("Camera Lens") }; + //lens.Add(); + //enemy.Add().scale = { 0.2f, 0.2f, 0.2f }; + //enemy.Get().position = { 0.0f, 0.0f, -3.0f }; + //enemy.Get().rotation = { 0.f, 0.f, 0.f }; + //enemy.Add(); + //CModel& cm{ enemy.Add( "nanosuit.obj") }; + //cm.model->Load(); + //EntityRef cam{ TestWorld.Spawn(lens) }; + //cam.Get().position = glm::vec3{ 4.5f, 3.4f, 14.26f }; + //cam.Get().pitch = -11.f; + //cam.Get().yaw = -89.f; + //EntityRef EnemyA{ TestWorld.Spawn(enemy) }; + //// set SpawnNanos to false if you want higher FPS and less nanosuits + //std::vector nanos; + //if (g_SpawnNanos) + //{ + // std::vector nanos; + // for (int i{ 0 }; i < 10; ++i) + // { + // for (int j{ 0 }; j < 10; ++j) + // { + // nanos.emplace_back(EnemyA.Clone()); + // nanos.back().Get().position = glm::vec3{ i, 0, j }; + // } + // } + //} //Makes the Game exit on window close bool WindowOpen = true; @@ -217,7 +217,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(); From dacad588e33546affdefc10bc1da4e9de54c6540 Mon Sep 17 00:00:00 2001 From: Kyle Philistine Date: Thu, 26 Apr 2018 22:47:33 -0700 Subject: [PATCH 2/4] first iteration of undo/redo + working add component / remove component --- .../VMLayer/propertiesViewerVM.service.ts | 76 ++++++++-- .../propertiesViewer.component.ts | 133 +++++++++--------- .../PropertiesViewer/propertiesViewer.html | 44 +++--- .../PropertiesViewer/propertiesViewer.scss | 3 - Editor/src/app/app.module.ts | 2 + Editor/src/index.html | 1 + 6 files changed, 163 insertions(+), 96 deletions(-) delete mode 100644 Editor/src/app/PropertiesViewer/propertiesViewer.scss diff --git a/Editor/src/app/PropertiesViewer/VMLayer/propertiesViewerVM.service.ts b/Editor/src/app/PropertiesViewer/VMLayer/propertiesViewerVM.service.ts index 0c5cc13..4d131cf 100644 --- a/Editor/src/app/PropertiesViewer/VMLayer/propertiesViewerVM.service.ts +++ b/Editor/src/app/PropertiesViewer/VMLayer/propertiesViewerVM.service.ts @@ -6,13 +6,14 @@ 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'; -class propertyData { +export class propertyData { type: Object; injector: Injector; } -class property { +export class property { name: string; propertiesData: Array; constructor() { @@ -23,18 +24,53 @@ class property { @Injectable() export class PropertiesViewerVMService { - private componentTypes: Map; - public componentsList: Array; + private componentTypes : Map; + private undoRedoService : UndoRedoManagerService; + private componentsList : Array; + private gameObjectProperties : Array; constructor(private propertiesViewerService: PropertiesViewerService, - private injector: Injector) { + private injector: Injector, + private undoRedoManagerService: UndoRedoManagerService) { - this.componentsList = Array(); this.componentTypes = new Map(); + this.undoRedoService = undoRedoManagerService; + this.componentsList = Array(); + this.gameObjectProperties = Array(); this.getGameComponentsStructures(); } - public addComponentToPropertyViewer(componentName: string) : property { + // 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]; var componentProperty = new property(); @@ -65,11 +101,16 @@ export class PropertiesViewerVMService { } } } - return componentProperty; + this.gameObjectProperties.push(componentProperty); } - public getComponentsList() : Array { - return this.componentsList; + public removeComponentFromPropertyViewer = (componentName : string) => { + // remove the component from the properties viewer + for(var i = 0; i < this.gameObjectProperties.length; ++i) { + if(this.gameObjectProperties[i].name == componentName) { + this.gameObjectProperties.splice(i, 1); + } + } } @@ -178,4 +219,19 @@ export class PropertiesViewerVMService { 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 75d14a3..46e2e6e 100644 --- a/Editor/src/app/PropertiesViewer/propertiesViewer.component.ts +++ b/Editor/src/app/PropertiesViewer/propertiesViewer.component.ts @@ -7,77 +7,82 @@ 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 } from './VMLayer/propertiesViewerVM.service'; - +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: Array; + //List of components queried from the engine + // componentsList: Array; + + //Array of properties currently to be viewed + currentGameObjectProperties: Array; - //Array of properties currently to be viewed - currentGameObjectProperties: Array; - - constructor(@Inject(GoldenLayoutComponentState) private state: any, - @Inject(GoldenLayoutContainer) private container: GoldenLayout.Container, - private propertiesViewerVMService: PropertiesViewerVMService, - private service: PropertiesViewerService, - private injector: Injector) { - - this.currentGameObjectProperties = new Array(); - } - - ngOnInit() { - } - - getComponentsList() : Array { - return this.propertiesViewerVMService.getComponentsList(); - } - - addComponent(componentName: string) { - var componentProperty = this.propertiesViewerVMService.addComponentToPropertyViewer(componentName); - this.currentGameObjectProperties.push(componentProperty); - } + constructor(@Inject(GoldenLayoutComponentState) private state: any, + @Inject(GoldenLayoutContainer) private container: GoldenLayout.Container, + private propertiesViewerVMService: PropertiesViewerVMService, + private service: PropertiesViewerService, + private injector: Injector) { + + this.currentGameObjectProperties = new Array(); + } + + ngOnInit() { + } + + + getComponentsList() : Array { + return this.propertiesViewerVMService.getComponentsList(); + } + + getGameObjectProperties() : Array { + return this.propertiesViewerVMService.getGameObjectProperties(); + } + + addComponent(componentName: string) { + var componentProperty = this.propertiesViewerVMService.addComponent(componentName); + } + + removeComponent(componentName:string) { + this.propertiesViewerVMService.removeComponent(componentName); + } - - 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 glOnShow(): void { - console.log('Game Object Properties Showing!'); - } - - public glOnHide(): void { - console.log('Game Object Properties Hiding!'); - } - + handleKeyEvents(keyEvent: KeyboardEvent) { + // undo + if(keyEvent.ctrlKey && keyEvent.keyCode == 90) { + this.propertiesViewerVMService.undoEventTrigger(); + } + + // redo + if(keyEvent.ctrlKey && keyEvent.keyCode == 89) { + this.propertiesViewerVMService.redoEventTrigger(); + } + } + + + 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 glOnShow(): void { + console.log('Game Object Properties Showing!'); + } + + public glOnHide(): void { + console.log('Game Object Properties Hiding!'); + } } \ No newline at end of file diff --git a/Editor/src/app/PropertiesViewer/propertiesViewer.html b/Editor/src/app/PropertiesViewer/propertiesViewer.html index 41e4482..5f403c0 100644 --- a/Editor/src/app/PropertiesViewer/propertiesViewer.html +++ b/Editor/src/app/PropertiesViewer/propertiesViewer.html @@ -1,22 +1,28 @@ -
- - - {{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/app.module.ts b/Editor/src/app/app.module.ts index 23e39f0..5ee11a7 100644 --- a/Editor/src/app/app.module.ts +++ b/Editor/src/app/app.module.ts @@ -26,6 +26,7 @@ import { HierachyViewerComponent } from './HierachyViewer/hierachyViewer.compone 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'; @@ -179,6 +180,7 @@ const goldenLayoutConfig: GoldenLayoutConfiguration = { // DEFAULT_LOCAL_STORAGE_STATE_STORE_PROVIDER PropertiesViewerService, PropertiesViewerVMService, + UndoRedoManagerService, PropertyLabels ], bootstrap: [AppComponent] 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 @@ + From baa7b48ba4405db3f0c7041815105874c7e619bc Mon Sep 17 00:00:00 2001 From: Kyle Philistine Date: Tue, 5 Jun 2018 01:50:14 -0700 Subject: [PATCH 3/4] Small Undo/Redo Fixes: + Undo had a bug where it was calling the redo's callback + a global static was set up in the Undo/Redo call for other Modules use Menu Bar: + Added View option to the bar, with some stubbed out view options + changed the font color to something more readable Hierarchy Viewer: + created an instance of the a golden layout container, this enabled me to use resize feature for undo/redo testing --- .../hierachyViewer.component.ts | 59 +++++++------ Editor/src/app/MenuBar/menuBar.component.ts | 39 ++++++++- Editor/src/app/MenuBar/menuBar.html | 8 ++ .../app/MenuBar/{menuBar.css => menuBar.scss} | 8 ++ .../VMLayer/propertiesViewerVM.service.ts | 19 +++- .../propertiesViewer.component.ts | 20 ----- .../app/PropertiesViewer/propertiesViewer.css | 10 +++ .../PropertiesViewer/propertiesViewer.html | 1 - Editor/src/app/app.component.ts | 36 ++++++++ Editor/src/app/app.module.ts | 1 + .../Utils/UndoRedo/UndoRedoManager.service.ts | 86 +++++++++++++++++++ 11 files changed, 236 insertions(+), 51 deletions(-) rename Editor/src/app/MenuBar/{menuBar.css => menuBar.scss} (77%) create mode 100644 Editor/src/app/PropertiesViewer/propertiesViewer.css create mode 100644 Editor/src/assets/Utils/UndoRedo/UndoRedoManager.service.ts diff --git a/Editor/src/app/HierachyViewer/hierachyViewer.component.ts b/Editor/src/app/HierachyViewer/hierachyViewer.component.ts index f1c2e0f..308a045 100644 --- a/Editor/src/app/HierachyViewer/hierachyViewer.component.ts +++ b/Editor/src/app/HierachyViewer/hierachyViewer.component.ts @@ -1,42 +1,47 @@ -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{ + undoRedoManager : UndoRedoManagerService; + 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) { + this.undoRedoManager = UndoRedoManagerService.getInstance(); + this.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() { + } } \ 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..a17bdcf 100644 --- a/Editor/src/app/MenuBar/menuBar.component.ts +++ b/Editor/src/app/MenuBar/menuBar.component.ts @@ -4,12 +4,13 @@ import { MatMenuTrigger } from '@angular/material/menu'; @Component({ selector: 'menu-bar', templateUrl: './menuBar.html', - styleUrls: ['./menuBar.css'], + styleUrls: ['./menuBar.scss'], }) export class MenuBarComponent { // File dropdown options: gFileOptions: Array; gEditOptions: Array; + gViewOptions: Array; // File Options for Menu Bar: MenuButton_NewProjectTrigger() { @@ -45,6 +46,23 @@ export class MenuBarComponent { console.log("Delete Menu Button!"); } + // View Options for Menu Bar + MenuButton_ViewProperties() { + console.log("View Properties Menu Button!"); + } + + MenuButton_ViewHierarchy() { + console.log("View Hierarchy Menu Button!"); + } + + MenuButton_ViewScene() { + console.log("View Scene Menu Button!"); + } + + MenuButton_ViewConsole() { + console.log("View Console Menu Button!"); + } + constructor() { this.gFileOptions = [ @@ -85,5 +103,24 @@ export class MenuBarComponent { onclickTrigger: this.MenuButton_DeleteTrigger } ]; + + this.gViewOptions = [ + { + optionName: "Properties", + onclickTrigger: this.MenuButton_ViewProperties + }, + { + optionName: "Hierarchy", + onclickTrigger: this.MenuButton_ViewHierarchy + }, + { + optionName: "Scene", + onclickTrigger: this.MenuButton_ViewScene + }, + { + optionName: "Console", + onclickTrigger: this.MenuButton_ViewConsole + } + ]; } } diff --git a/Editor/src/app/MenuBar/menuBar.html b/Editor/src/app/MenuBar/menuBar.html index db1f1aa..f3b0163 100644 --- a/Editor/src/app/MenuBar/menuBar.html +++ b/Editor/src/app/MenuBar/menuBar.html @@ -2,6 +2,7 @@ + @@ -17,4 +18,11 @@ + + + +
+ +
+
\ 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/PropertiesViewer/VMLayer/propertiesViewerVM.service.ts b/Editor/src/app/PropertiesViewer/VMLayer/propertiesViewerVM.service.ts index 4d131cf..bbaf90e 100644 --- a/Editor/src/app/PropertiesViewer/VMLayer/propertiesViewerVM.service.ts +++ b/Editor/src/app/PropertiesViewer/VMLayer/propertiesViewerVM.service.ts @@ -33,8 +33,9 @@ export class PropertiesViewerVMService { private injector: Injector, private undoRedoManagerService: UndoRedoManagerService) { + + this.undoRedoService = UndoRedoManagerService.getInstance(); this.componentTypes = new Map(); - this.undoRedoService = undoRedoManagerService; this.componentsList = Array(); this.gameObjectProperties = Array(); this.getGameComponentsStructures(); @@ -72,6 +73,12 @@ export class PropertiesViewerVMService { // 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; @@ -105,9 +112,17 @@ export class PropertiesViewerVMService { } public removeComponentFromPropertyViewer = (componentName : string) => { + 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 == componentName) { + if(this.gameObjectProperties[i].name == realComponentName) { this.gameObjectProperties.splice(i, 1); } } diff --git a/Editor/src/app/PropertiesViewer/propertiesViewer.component.ts b/Editor/src/app/PropertiesViewer/propertiesViewer.component.ts index 46e2e6e..f9df70b 100644 --- a/Editor/src/app/PropertiesViewer/propertiesViewer.component.ts +++ b/Editor/src/app/PropertiesViewer/propertiesViewer.component.ts @@ -18,25 +18,18 @@ import * as GoldenLayout from 'golden-layout'; }) export class PropertiesViewerComponent implements GlOnResize, GlOnHide, GlOnShow { - //List of components queried from the engine - // componentsList: Array; - //Array of properties currently to be viewed - currentGameObjectProperties: Array; - constructor(@Inject(GoldenLayoutComponentState) private state: any, @Inject(GoldenLayoutContainer) private container: GoldenLayout.Container, private propertiesViewerVMService: PropertiesViewerVMService, private service: PropertiesViewerService, private injector: Injector) { - this.currentGameObjectProperties = new Array(); } ngOnInit() { } - getComponentsList() : Array { return this.propertiesViewerVMService.getComponentsList(); } @@ -53,19 +46,6 @@ export class PropertiesViewerComponent implements GlOnResize, GlOnHide, GlOnShow this.propertiesViewerVMService.removeComponent(componentName); } - handleKeyEvents(keyEvent: KeyboardEvent) { - // undo - if(keyEvent.ctrlKey && keyEvent.keyCode == 90) { - this.propertiesViewerVMService.undoEventTrigger(); - } - - // redo - if(keyEvent.ctrlKey && keyEvent.keyCode == 89) { - this.propertiesViewerVMService.redoEventTrigger(); - } - } - - public onInput(e: Event): void { this.container.extendState({ value: (e.target).value 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 5f403c0..598db88 100644 --- a/Editor/src/app/PropertiesViewer/propertiesViewer.html +++ b/Editor/src/app/PropertiesViewer/propertiesViewer.html @@ -1,5 +1,4 @@
-
diff --git a/Editor/src/app/app.component.ts b/Editor/src/app/app.component.ts index 84b9bfc..155a3a5 100644 --- a/Editor/src/app/app.component.ts +++ b/Editor/src/app/app.component.ts @@ -1,5 +1,6 @@ import { Component, OnInit } from '@angular/core'; import { MenuBarComponent } from './MenuBar/menuBar.component'; +import { UndoRedoManagerService } from '../assets/Utils/UndoRedo/UndoRedoManager.service'; @Component({ selector: 'editor', @@ -12,6 +13,41 @@ import { MenuBarComponent } from './MenuBar/menuBar.component'; //templateUrl: './app.component.html', styleUrls: ['./app.component.css'] }) + export class AppComponent { + undoRedoManager : UndoRedoManagerService; + constructor() { + this.undoRedoManager = UndoRedoManagerService.getInstance(); + } + //title = 'app'; + ngOnInit() { + this.LoadEventListeners(); + } + + + 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 5ee11a7..c3f4cc3 100644 --- a/Editor/src/app/app.module.ts +++ b/Editor/src/app/app.module.ts @@ -45,6 +45,7 @@ import * as GoldenLayout from 'golden-layout'; import * as Jquery from 'jquery'; import { AppComponent } from './app.component'; + const goldenLayoutConfig: GoldenLayoutConfiguration = { components: [ { 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 From 20044041f2168781524392edbae196dd1af332be Mon Sep 17 00:00:00 2001 From: Kyle Philistine Date: Mon, 11 Jun 2018 18:08:23 -0700 Subject: [PATCH 4/4] Menu Bar: + can now open Properties View + can now open Hierarchy View + can now open Scene View + can now open Project View + can now open Console View All buttons in the "View" dropdown on the Menu Bar are all functional. If the window is not active, you can open a new one. You can only open a new window if there is currently no active window for the one you chose. Only 1 of each window can be active at a time. --- .../ConsoleViewer/consoleViewer.component.ts | 43 ++ .../src/app/ConsoleViewer/consoleViewer.html | 0 .../src/app/ConsoleViewer/consoleViewer.scss | 0 .../hierachyViewer.component.ts | 10 +- Editor/src/app/MenuBar/menuBar.component.ts | 456 +++++++++++++----- Editor/src/app/MenuBar/menuBar.html | 6 +- .../ProjectViewer/projectViewer.component.ts | 6 +- .../VMLayer/propertiesViewerVM.service.ts | 2 + .../propertiesViewer.component.ts | 19 +- .../app/SceneViewer/sceneViewer.component.ts | 6 +- Editor/src/app/app.component.ts | 59 +-- Editor/src/app/app.module.ts | 64 ++- 12 files changed, 492 insertions(+), 179 deletions(-) create mode 100644 Editor/src/app/ConsoleViewer/consoleViewer.component.ts create mode 100644 Editor/src/app/ConsoleViewer/consoleViewer.html create mode 100644 Editor/src/app/ConsoleViewer/consoleViewer.scss 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 308a045..eea0ef9 100644 --- a/Editor/src/app/HierachyViewer/hierachyViewer.component.ts +++ b/Editor/src/app/HierachyViewer/hierachyViewer.component.ts @@ -14,13 +14,11 @@ import * as GoldenLayout from 'golden-layout'; @Inject(GoldenLayoutContainer) export class HierachyViewerComponent implements GlOnResize, GlOnHide, GlOnShow{ - undoRedoManager : UndoRedoManagerService; - containerManager : GoldenLayout.Container; + public static containerManager : GoldenLayout.Container; constructor(@Inject(GoldenLayoutComponentState) private state: any, @Inject(GoldenLayoutContainer) private container: GoldenLayout.Container) { - this.undoRedoManager = UndoRedoManagerService.getInstance(); - this.containerManager = container; + HierachyViewerComponent.containerManager = container; } public onInput(e: Event): void { @@ -44,4 +42,8 @@ export class HierachyViewerComponent implements GlOnResize, GlOnHide, GlOnShow{ 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 a17bdcf..852d1cb 100644 --- a/Editor/src/app/MenuBar/menuBar.component.ts +++ b/Editor/src/app/MenuBar/menuBar.component.ts @@ -1,126 +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.scss'], + selector: 'menu-bar', + templateUrl: './menuBar.html', + styleUrls: ['./menuBar.scss'] }) + + export class MenuBarComponent { // File dropdown options: - gFileOptions: Array; - gEditOptions: Array; - gViewOptions: Array; + gFileOptions : Array; + gEditOptions : Array; + gViewOptions : Array; + + gDragSourcesInit : Boolean = false; + public static gConsoleViewExists : Boolean = false; + public static gHierarchyViewExists : Boolean = true; + public static gPropertiesViewExists : Boolean = true; + public static gSceneViewExists : Boolean = true; + public static gProjectViewExists : Boolean = true; + + private gClosedConsoleOnStart : Boolean = false; + + // make sure the views are properly set up with their event handlers + private gConsoleContainerInit : Boolean = false; + private gHierarchyContainerInit : Boolean = false; + private gPropertiesContainerInit : Boolean = false; + private gSceneContainerInit : Boolean = false; + private gProjectContainerInit : Boolean = false; // File Options for Menu Bar: - MenuButton_NewProjectTrigger() { - console.log("New Project Menu Button!"); - } + MenuButton_NewProjectTrigger() { + console.log("New Project Menu Button!"); + } - MenuButton_OpenProjectTrigger() { - console.log("Open Project Menu Button!"); - } + MenuButton_OpenProjectTrigger() { + console.log("Open Project Menu Button!"); + } - MenuButton_SaveProjectTrigger() { - console.log("Save Project Menu Button!"); - } + MenuButton_SaveProjectTrigger() { + console.log("Save Project Menu Button!"); + } // Edit Options for Menu Bar - MenuButton_CutTrigger() { - console.log("Cut Menu Button!"); - } - - MenuButton_CopyTrigger() { - console.log("Copy Menu Button!"); - } - - MenuButton_PasteTrigger() { - console.log("Paste Menu Button!"); - } - - MenuButton_DuplicateTrigger() { - console.log("Duplicate Menu Button!"); - } - - MenuButton_DeleteTrigger() { - console.log("Delete Menu Button!"); - } - - // View Options for Menu Bar - MenuButton_ViewProperties() { - console.log("View Properties Menu Button!"); - } - - MenuButton_ViewHierarchy() { - console.log("View Hierarchy Menu Button!"); - } - - MenuButton_ViewScene() { - console.log("View Scene Menu Button!"); - } - - MenuButton_ViewConsole() { - console.log("View Console Menu Button!"); - } - - - constructor() { - this.gFileOptions = [ - { - optionName: "New Project", - onclickTrigger: this.MenuButton_NewProjectTrigger - }, - { - optionName: "Open Project", - onclickTrigger: this.MenuButton_OpenProjectTrigger - }, - { - optionName: "Save Project", - onclickTrigger: this.MenuButton_SaveProjectTrigger - } - ]; - - // set up the Edit Function Menu, sets up the name for each button as well as the triggers - this.gEditOptions = [ - { - optionName: "Cut", - onclickTrigger: this.MenuButton_CutTrigger - }, - { - optionName: "Copy", - onclickTrigger: this.MenuButton_CopyTrigger - }, - { - optionName: "Paste", - onclickTrigger: this.MenuButton_PasteTrigger - }, - { - optionName: "Duplicate", - onclickTrigger: this.MenuButton_DuplicateTrigger - }, - { - optionName: "Delete", - onclickTrigger: this.MenuButton_DeleteTrigger - } - ]; - - this.gViewOptions = [ - { - optionName: "Properties", - onclickTrigger: this.MenuButton_ViewProperties - }, - { - optionName: "Hierarchy", - onclickTrigger: this.MenuButton_ViewHierarchy - }, - { - optionName: "Scene", - onclickTrigger: this.MenuButton_ViewScene - }, - { - optionName: "Console", - onclickTrigger: this.MenuButton_ViewConsole - } - ]; - } + MenuButton_CutTrigger() { + console.log("Cut Menu Button!"); + } + + MenuButton_CopyTrigger() { + console.log("Copy Menu Button!"); + } + + MenuButton_PasteTrigger() { + console.log("Paste Menu Button!"); + } + + MenuButton_DuplicateTrigger() { + console.log("Duplicate Menu Button!"); + } + + MenuButton_DeleteTrigger() { + console.log("Delete Menu Button!"); + } + + // View Options for Menu Bar + MenuButton_ViewProperties() { + var propertiesViewExists = MenuBarComponent.gPropertiesViewExists; + var containerManager = PropertiesViewerComponent.containerManager; + + if(propertiesViewExists) { + return; + } + + var newPropertiesViewConfig : GoldenLayout.ComponentConfig = { + type : "component", + width : 20, + height : 20, + componentName : "Properties" + } + + containerManager.layoutManager.root.contentItems[0].addChild(newPropertiesViewConfig); + MenuBarComponent.gPropertiesViewExists = true; + } + + MenuButton_ViewHierarchy() { + var hierarchyExists = MenuBarComponent.gHierarchyViewExists; + var containerManager = HierachyViewerComponent.containerManager; + + if(hierarchyExists) { + return; + } + + var newHierarchyViewConfig : GoldenLayout.ComponentConfig = { + type : "component", + width : 20, + height : 20, + componentName : "Hierarchy" + } + + containerManager.layoutManager.root.contentItems[0].addChild(newHierarchyViewConfig); + MenuBarComponent.gHierarchyViewExists = true; + } + + MenuButton_ViewScene() { + var sceneExists = MenuBarComponent.gSceneViewExists; + var containerManager = SceneViewerComponent.containerManager; + + if(sceneExists) { + return; + } + + var newSceneViewConfig : GoldenLayout.ComponentConfig = { + type : "component", + width : 20, + height : 20, + componentName : "Scene" + } + + containerManager.layoutManager.root.contentItems[0].addChild(newSceneViewConfig); + MenuBarComponent.gSceneViewExists = true; + } + + public MenuButton_ViewProject() { + var projectExists = MenuBarComponent.gProjectViewExists; + var containerManager = ProjectViewerComponent.containerManager; + + if(projectExists) { + return; + } + + var newProjectViewConfig : GoldenLayout.ComponentConfig = { + type : "component", + width : 20, + height : 20, + componentName : "Project" + } + + containerManager.layoutManager.root.contentItems[0].addChild(newProjectViewConfig); + MenuBarComponent.gProjectViewExists = true; + } + + public MenuButton_ViewConsole() { + var consoleExists = MenuBarComponent.gConsoleViewExists; + var containerManager = ConsoleViewerComponent.containerManager; + + if(consoleExists) { + return; + } + + var newConsoleViewConfig : GoldenLayout.ComponentConfig = { + type : "component", + width : 20, + height : 20, + componentName : "Console" + } + + containerManager.layoutManager.root.contentItems[0].addChild(newConsoleViewConfig); + MenuBarComponent.gConsoleViewExists = true; + } + + + private SetupMenuBarOptions() { + this.gFileOptions = [ + { + optionName: "New Project", + onclickTrigger: this.MenuButton_NewProjectTrigger + }, + { + optionName: "Open Project", + onclickTrigger: this.MenuButton_OpenProjectTrigger + }, + { + optionName: "Save Project", + onclickTrigger: this.MenuButton_SaveProjectTrigger + } + ]; + + // set up the Edit Function Menu, sets up the name for each button as well as the triggers + this.gEditOptions = [ + { + optionName: "Cut", + onclickTrigger: this.MenuButton_CutTrigger + }, + { + optionName: "Copy", + onclickTrigger: this.MenuButton_CopyTrigger + }, + { + optionName: "Paste", + onclickTrigger: this.MenuButton_PasteTrigger + }, + { + optionName: "Duplicate", + onclickTrigger: this.MenuButton_DuplicateTrigger + }, + { + optionName: "Delete", + onclickTrigger: this.MenuButton_DeleteTrigger + } + ]; + + this.gViewOptions = [ + { + optionName: "Properties", + onclickTrigger: this.MenuButton_ViewProperties + }, + { + optionName: "Hierarchy", + onclickTrigger: this.MenuButton_ViewHierarchy + }, + { + optionName: "Scene", + onclickTrigger: this.MenuButton_ViewScene + }, + { + optionName: "Project", + onclickTrigger: this.MenuButton_ViewProject + }, + { + optionName: "Console", + onclickTrigger: this.MenuButton_ViewConsole + } + ]; + } + + public showConsole() { + console.log("Console is now showing!"); + } + + + public getConsoleContainer() : GoldenLayout.Container { + return ConsoleViewerComponent.containerManager; + } + + + public getHierarchyContainer() : GoldenLayout.Container { + return HierachyViewerComponent.containerManager; + } + + public getPropertiesContainer() : GoldenLayout.Container { + return PropertiesViewerComponent.containerManager; + } + + public getSceneContainer() : GoldenLayout.Container { + return SceneViewerComponent.containerManager; + } + + public getProjectContainer() : GoldenLayout.Container { + return ProjectViewerComponent.containerManager; + } + + public InitViewDragSources() { + if(this.gDragSourcesInit == true) { + return; + } + + // TODO: Find a way to get drag to work with the views being created normally. + // Currently, when you drag a new window, it will create duplicates. + // Stop this from happening or remove the feature entirely + // var consoleViewItem = { + // type: 'component', + // width: 20, + // height: 20, + // componentName: 'Console', + // }; + //var consoleViewEle = document.getElementById("ConsoleView"); + // var dragsource = consoleContainer.layoutManager.createDragSource(consoleViewEle, consoleViewItem); + + // make sure this function only happens once when the 'View' button is clicked + this.gDragSourcesInit = true; + } + + constructor() { + this.SetupMenuBarOptions(); + } + + public ngAfterContentChecked() { + var consoleContainer = this.getConsoleContainer(); + var hierachyContainer = this.getHierarchyContainer(); + var propertiesContainer = this.getPropertiesContainer(); + var sceneContainer = this.getSceneContainer(); + var projectContainer = this.getProjectContainer(); + + if(consoleContainer && this.gConsoleContainerInit == false) { + // intercept the itemDestroyed event and toggle the ConsoleExists flag, to open the window later on request. + consoleContainer.layoutManager.on('itemDestroyed', function(event) { + if(event.componentName && event.componentName == "Console") { + MenuBarComponent.gConsoleViewExists = false; + } + }, null); + + this.gConsoleContainerInit = true; + } + + if(hierachyContainer && this.gHierarchyContainerInit == false) { + hierachyContainer.layoutManager.on('itemDestroyed', function(event) { + if(event.componentName && event.componentName == "Hierarchy") { + MenuBarComponent.gHierarchyViewExists = false; + } + }, null); + + this.gHierarchyContainerInit = true; + } + + if(propertiesContainer && this.gPropertiesContainerInit == false) { + propertiesContainer.layoutManager.on('itemDestroyed', function(event) { + if(event.componentName && event.componentName == "Properties") { + MenuBarComponent.gPropertiesViewExists = false; + } + }, null); + + this.gPropertiesContainerInit = true; + } + + if(sceneContainer && this.gSceneContainerInit == false) { + sceneContainer.layoutManager.on('itemDestroyed', function(event) { + if(event.componentName && event.componentName == "Scene") { + MenuBarComponent.gSceneViewExists = false; + } + }, null); + + this.gSceneContainerInit = true; + } + + if(projectContainer && this.gProjectContainerInit == false) { + projectContainer.layoutManager.on('itemDestroyed', function(event) { + if(event.componentName && event.componentName == "Project") { + MenuBarComponent.gProjectViewExists = false; + } + }, null); + + this.gProjectContainerInit = true; + } + + // close the hidden console that was made on start up. Needed for getting a reference to the console's container + if(consoleContainer && consoleContainer.height !== null && consoleContainer.width !== null && this.gClosedConsoleOnStart == false) { + consoleContainer.close(); + this.gClosedConsoleOnStart = true; + } + } } diff --git a/Editor/src/app/MenuBar/menuBar.html b/Editor/src/app/MenuBar/menuBar.html index f3b0163..9ff729b 100644 --- a/Editor/src/app/MenuBar/menuBar.html +++ b/Editor/src/app/MenuBar/menuBar.html @@ -2,7 +2,7 @@ - + @@ -22,7 +22,9 @@
- +
+ +
\ No newline at end of file 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 index bbaf90e..fb2c7f3 100644 --- a/Editor/src/app/PropertiesViewer/VMLayer/propertiesViewerVM.service.ts +++ b/Editor/src/app/PropertiesViewer/VMLayer/propertiesViewerVM.service.ts @@ -112,6 +112,8 @@ export class PropertiesViewerVMService { } 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']; diff --git a/Editor/src/app/PropertiesViewer/propertiesViewer.component.ts b/Editor/src/app/PropertiesViewer/propertiesViewer.component.ts index f9df70b..5165e0a 100644 --- a/Editor/src/app/PropertiesViewer/propertiesViewer.component.ts +++ b/Editor/src/app/PropertiesViewer/propertiesViewer.component.ts @@ -18,16 +18,13 @@ import * as GoldenLayout from 'golden-layout'; }) export class PropertiesViewerComponent implements GlOnResize, GlOnHide, GlOnShow { - + public static containerManager : GoldenLayout.Container; + constructor(@Inject(GoldenLayoutComponentState) private state: any, @Inject(GoldenLayoutContainer) private container: GoldenLayout.Container, - private propertiesViewerVMService: PropertiesViewerVMService, - private service: PropertiesViewerService, - private injector: Injector) { - - } - - ngOnInit() { + private propertiesViewerVMService: PropertiesViewerVMService) { + + PropertiesViewerComponent.containerManager = container; } getComponentsList() : Array { @@ -65,4 +62,10 @@ export class PropertiesViewerComponent implements GlOnResize, GlOnHide, GlOnShow 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/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 155a3a5..da14145 100644 --- a/Editor/src/app/app.component.ts +++ b/Editor/src/app/app.component.ts @@ -1,53 +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 { - undoRedoManager : UndoRedoManagerService; - constructor() { - this.undoRedoManager = UndoRedoManagerService.getInstance(); - } + undoRedoManager : UndoRedoManagerService; + + constructor() { + this.undoRedoManager = UndoRedoManagerService.getInstance(); + } - //title = 'app'; - ngOnInit() { - this.LoadEventListeners(); - } + ngOnInit() { + this.LoadEventListeners(); + } - LoadEventListeners() { - document.addEventListener('keydown', (event) => { + + private LoadEventListeners() { + document.addEventListener('keydown', (event) => { const keyName = event.key; if(keyName === 'Control') { return; } if(event.ctrlKey) { - // undo, Ctrl+Z + // undo, Ctrl+Z if(event.keyCode == 90) { - this.undoRedoManager.Undo(); - return; + this.undoRedoManager.Undo(); + return; } - // redo, Ctrl+Y + // redo, Ctrl+Y if(event.keyCode == 89) { - this.undoRedoManager.Redo(); - return; + this.undoRedoManager.Redo(); + return; } } - } - ) -} + }) + } } diff --git a/Editor/src/app/app.module.ts b/Editor/src/app/app.module.ts index c3f4cc3..bf235fd 100644 --- a/Editor/src/app/app.module.ts +++ b/Editor/src/app/app.module.ts @@ -33,6 +33,7 @@ import { SliderViewer } from './PropertiesViewer/Properties/sliderViewer/sliderV 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'; @@ -66,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', @@ -91,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', + }, + ] }] } } @@ -138,6 +156,7 @@ const goldenLayoutConfig: GoldenLayoutConfiguration = { ProjectViewerComponent, HierachyViewerComponent, PropertiesViewerComponent, + ConsoleViewerComponent, MenuBarComponent, ContextMenuComponent, Vector3Viewer, @@ -154,6 +173,7 @@ const goldenLayoutConfig: GoldenLayoutConfiguration = { HierachyViewerComponent, MenuBarComponent, PropertiesViewerComponent, + ConsoleViewerComponent, Vector3Viewer, Vector2Viewer, SliderViewer, @@ -186,4 +206,6 @@ const goldenLayoutConfig: GoldenLayoutConfiguration = { ], bootstrap: [AppComponent] }) -export class AppModule { } + +export class AppModule { +}