diff --git a/src/app/app.module.ts b/src/app/app.module.ts index 7412843..c1e95d8 100644 --- a/src/app/app.module.ts +++ b/src/app/app.module.ts @@ -70,6 +70,18 @@ import { } from "./editor/gamesystem-editor/scriptaccount-condition-editor/scriptaccount-condition-editor.component"; import {CharacterOverviewComponent} from "./side-overviews/character-overview/character-overview.component"; import {CharacterEditorComponent} from "./editor/character-editor/character-editor.component"; +import { + TemplateGamesystemEditorComponent +} from "./editor/gamesystem-editor/template-gamesystem-editor/template-gamesystem-editor.component"; +import { + TemplateStateEditorComponent +} from "./editor/gamesystem-editor/template-gamesystem-editor/template-state-editor/template-state-editor.component"; +import { + MatAccordion, + MatExpansionPanel, + MatExpansionPanelHeader, + MatExpansionPanelTitle +} from "@angular/material/expansion"; // AoT requires an exported function for factories const httpLoaderFactory = (http: HttpClient): TranslateHttpLoader => new TranslateHttpLoader(http, './assets/i18n/', '.json'); @@ -93,7 +105,9 @@ const httpLoaderFactory = (http: HttpClient): TranslateHttpLoader => new Transl ScriptaccountActionEditorComponent, ScriptaccountConditionEditorComponent, CharacterOverviewComponent, - CharacterEditorComponent + CharacterEditorComponent, + TemplateGamesystemEditorComponent, + TemplateStateEditorComponent ], imports: [ BrowserModule, @@ -150,9 +164,16 @@ const httpLoaderFactory = (http: HttpClient): TranslateHttpLoader => new Transl MatHint, MatTooltip, MatCard, - MatCardContent + MatCardContent, + MatAccordion, + MatExpansionPanel, + MatExpansionPanelTitle, + MatExpansionPanelHeader ], providers: [], + exports: [ + ProductGamesystemEditorComponent + ], bootstrap: [AppComponent] }) export class AppModule {} diff --git a/src/app/editor/character-editor/character-editor.component.html b/src/app/editor/character-editor/character-editor.component.html index 4750ae3..4844143 100644 --- a/src/app/editor/character-editor/character-editor.component.html +++ b/src/app/editor/character-editor/character-editor.component.html @@ -1 +1,8 @@ -

character-editor works!

+ + + + {{templateGamesystem.referenceGamesystem.componentName}} + + + + diff --git a/src/app/editor/character-editor/character-editor.component.ts b/src/app/editor/character-editor/character-editor.component.ts index 23e8438..8d0a829 100644 --- a/src/app/editor/character-editor/character-editor.component.ts +++ b/src/app/editor/character-editor/character-editor.component.ts @@ -1,10 +1,31 @@ -import { Component } from '@angular/core'; +import {Component, Input, OnInit} from '@angular/core'; +import {Character} from "../../project/game-model/characters/Character"; +import {Gamesystem} from "../../project/game-model/gamesystems/Gamesystem"; +import {TemplateGamesystem} from "../../project/game-model/gamesystems/TemplateGamesystem"; +import {ProductGamesystem} from "../../project/game-model/gamesystems/ProductGamesystem"; +import {SimpleGamesystem} from "../../project/game-model/gamesystems/SimpleGamesystem"; @Component({ selector: 'app-character-editor', templateUrl: './character-editor.component.html', styleUrl: './character-editor.component.scss' }) -export class CharacterEditorComponent { +export class CharacterEditorComponent implements OnInit{ + + @Input() character: Character | undefined + @Input() referenceGamesystems: Gamesystem[] = [] + + templateSimpleGamesystems: TemplateGamesystem[] = [] + templateProductGamesystems: ProductGamesystem[] = [] + + ngOnInit() { + this.referenceGamesystems.forEach(referenceGamesystem => { + if(referenceGamesystem instanceof SimpleGamesystem) { + this.templateSimpleGamesystems.push(new TemplateGamesystem(referenceGamesystem)) + } else { + this.templateProductGamesystems.push(referenceGamesystem as ProductGamesystem) + } + }) + } } diff --git a/src/app/editor/editor.component.html b/src/app/editor/editor.component.html index b351774..3009a7f 100644 --- a/src/app/editor/editor.component.html +++ b/src/app/editor/editor.component.html @@ -14,7 +14,9 @@ [gamesystem]="convertModelComponentToGamesystem(modelComponent)" (onOpenGamesystemEditor)="openGameModelComponent($event)" [scriptAccounts]="gameModel!.scriptAccounts"> - + diff --git a/src/app/editor/editor.component.ts b/src/app/editor/editor.component.ts index 887f4d8..efba596 100644 --- a/src/app/editor/editor.component.ts +++ b/src/app/editor/editor.component.ts @@ -6,6 +6,9 @@ import {Gamesystem} from "../project/game-model/gamesystems/Gamesystem"; import {State} from "../project/game-model/gamesystems/states/State"; import {Transition} from "../project/game-model/gamesystems/transitions/Transition"; import {ModelComponentType} from "../project/game-model/ModelComponentType"; +import {Character} from "../project/game-model/characters/Character"; +import {TemplateType} from "../project/game-model/gamesystems/TemplateType"; +import {load} from "@angular-devkit/build-angular/src/utils/server-rendering/esm-in-memory-loader/loader-hooks"; @Component({ @@ -44,10 +47,20 @@ export class EditorComponent { } } + convertModelComponentToCharacter(modelComponent: ModelComponent) { + if(modelComponent instanceof Character) { + return modelComponent as Character + } + } + onModelNameUpdate() { this.onModelNameUpdateEmitter.emit(true); } + loadCharacterSpecificGamesystems() { + return this.gameModel!.gamesystems.filter(gamesystem => gamesystem.template == TemplateType.CHARACTER); + } + protected readonly ModelComponentType = ModelComponentType; } diff --git a/src/app/editor/gamesystem-editor/state-editor/simple-state-editor/simple-state-editor.component.ts b/src/app/editor/gamesystem-editor/state-editor/simple-state-editor/simple-state-editor.component.ts index 049814c..0091c19 100644 --- a/src/app/editor/gamesystem-editor/state-editor/simple-state-editor/simple-state-editor.component.ts +++ b/src/app/editor/gamesystem-editor/state-editor/simple-state-editor/simple-state-editor.component.ts @@ -1,4 +1,4 @@ -import {Component, Input, OnInit} from '@angular/core'; +import {Component, EventEmitter, Input, OnChanges, OnInit, Output} from '@angular/core'; import {MatTableDataSource} from "@angular/material/table"; import {animate, state, style, transition, trigger} from "@angular/animations"; import {MatSnackBar} from "@angular/material/snack-bar"; @@ -6,6 +6,7 @@ import {SimpleState} from "../../../../project/game-model/gamesystems/states/Sim import {SimpleGamesystem} from "../../../../project/game-model/gamesystems/SimpleGamesystem"; import {ScriptAccount} from "../../../../project/game-model/scriptAccounts/ScriptAccount"; import {ScriptAccountCondition} from "../../../../project/game-model/gamesystems/conditions/ScriptAccountCondition"; +import {TemplateGamesystem} from "../../../../project/game-model/gamesystems/TemplateGamesystem"; @Component({ selector: 'app-simple-state-editor', @@ -19,11 +20,12 @@ import {ScriptAccountCondition} from "../../../../project/game-model/gamesystems ]), ], }) -export class SimpleStateEditorComponent implements OnInit{ +export class SimpleStateEditorComponent implements OnInit, OnChanges{ @Input() states: SimpleState[] = []; - @Input() gamesystem: SimpleGamesystem | undefined + @Input() gamesystem: SimpleGamesystem | undefined @Input() scriptAccounts: ScriptAccount[] = [] + @Output() onExtractReferenceState = new EventEmitter() dataSource = new MatTableDataSource(); displayedColumns = ["name", "initial", "edit", "delete"]; columnsToDisplayWithExpand = [...this.displayedColumns, 'expand']; @@ -40,13 +42,30 @@ export class SimpleStateEditorComponent implements OnInit{ this.dataSource.filterPredicate = (data: SimpleState, filter: string) => { return data.stateLabel.toLowerCase().includes(filter); } + + if(this.gamesystem == undefined) { + this.displayedColumns = this.displayedColumns.slice(0, -1); + this.columnsToDisplayWithExpand = [... this.displayedColumns, 'expand'] + } + } + + ngOnChanges() { + this.dataSource.data = this.states; + this.dataSource.filterPredicate = (data: SimpleState, filter: string) => { + return data.stateLabel.toLowerCase().includes(filter); + } + console.log(this.states.length) } editState(state: SimpleState) { - if(this.editedElement === state) { - this.editedElement = null; + if(this.gamesystem == undefined) { + this.onExtractReferenceState.emit(state) } else { - this.editedElement = state; + if(this.editedElement === state) { + this.editedElement = null; + } else { + this.editedElement = state; + } } } diff --git a/src/app/editor/gamesystem-editor/template-gamesystem-editor/template-gamesystem-editor.component.html b/src/app/editor/gamesystem-editor/template-gamesystem-editor/template-gamesystem-editor.component.html new file mode 100644 index 0000000..4471bdf --- /dev/null +++ b/src/app/editor/gamesystem-editor/template-gamesystem-editor/template-gamesystem-editor.component.html @@ -0,0 +1 @@ + diff --git a/src/app/editor/gamesystem-editor/template-gamesystem-editor/template-gamesystem-editor.component.scss b/src/app/editor/gamesystem-editor/template-gamesystem-editor/template-gamesystem-editor.component.scss new file mode 100644 index 0000000..e69de29 diff --git a/src/app/editor/gamesystem-editor/template-gamesystem-editor/template-gamesystem-editor.component.spec.ts b/src/app/editor/gamesystem-editor/template-gamesystem-editor/template-gamesystem-editor.component.spec.ts new file mode 100644 index 0000000..7ddadba --- /dev/null +++ b/src/app/editor/gamesystem-editor/template-gamesystem-editor/template-gamesystem-editor.component.spec.ts @@ -0,0 +1,23 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { TemplateGamesystemEditorComponent } from './template-gamesystem-editor.component'; + +describe('TemplateGamesystemEditorComponent', () => { + let component: TemplateGamesystemEditorComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + imports: [TemplateGamesystemEditorComponent] + }) + .compileComponents(); + + fixture = TestBed.createComponent(TemplateGamesystemEditorComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/editor/gamesystem-editor/template-gamesystem-editor/template-gamesystem-editor.component.ts b/src/app/editor/gamesystem-editor/template-gamesystem-editor/template-gamesystem-editor.component.ts new file mode 100644 index 0000000..e04554d --- /dev/null +++ b/src/app/editor/gamesystem-editor/template-gamesystem-editor/template-gamesystem-editor.component.ts @@ -0,0 +1,17 @@ +import {Component, Input} from '@angular/core'; +import {SimpleGamesystem} from "../../../project/game-model/gamesystems/SimpleGamesystem"; +import {ScriptAccount} from "../../../project/game-model/scriptAccounts/ScriptAccount"; +import {Gamesystem} from "../../../project/game-model/gamesystems/Gamesystem"; +import {ProductGamesystem} from "../../../project/game-model/gamesystems/ProductGamesystem"; +import {TemplateGamesystem} from "../../../project/game-model/gamesystems/TemplateGamesystem"; + +@Component({ + selector: 'app-template-gamesystem-editor', + templateUrl: './template-gamesystem-editor.component.html', + styleUrl: './template-gamesystem-editor.component.scss' +}) +export class TemplateGamesystemEditorComponent { + @Input() gamesystem: TemplateGamesystem | undefined + @Input() scriptAccunts: ScriptAccount[] = [] + +} diff --git a/src/app/editor/gamesystem-editor/template-gamesystem-editor/template-state-editor/template-state-editor.component.html b/src/app/editor/gamesystem-editor/template-gamesystem-editor/template-state-editor/template-state-editor.component.html new file mode 100644 index 0000000..a7c9873 --- /dev/null +++ b/src/app/editor/gamesystem-editor/template-gamesystem-editor/template-state-editor/template-state-editor.component.html @@ -0,0 +1,91 @@ +
+
+ + + + Filter + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Label + {{state.stateLabel}} + +
+

{{element.stateDescription}}

+ +
+ +
+
+
Initial +
+ done + close +
+ + +
+ + + + + + + +
+ +
+
+ +
+
+ +
+
diff --git a/src/app/editor/gamesystem-editor/template-gamesystem-editor/template-state-editor/template-state-editor.component.scss b/src/app/editor/gamesystem-editor/template-gamesystem-editor/template-state-editor/template-state-editor.component.scss new file mode 100644 index 0000000..089d1bf --- /dev/null +++ b/src/app/editor/gamesystem-editor/template-gamesystem-editor/template-state-editor/template-state-editor.component.scss @@ -0,0 +1,65 @@ +.state-editor-container { + display: flex; +} + +table { + width: 100%; +} + +tr.example-detail-row { + height: 0; +} + +tr.example-element-row:not(.example-expanded-row):hover { + background: #545456 +} + +tr.example-element-row:not(.example-expanded-row):active { + background: #545456; +} + +.example-element-row td { + border-bottom-width: 0; +} +.example-element-diagram { + min-width: 80px; + border: 2px solid black; + padding: 8px; + font-weight: lighter; + margin: 8px 0; + height: 104px; +} + +.example-element-symbol { + font-weight: bold; + font-size: 40px; + line-height: normal; +} + +.example-element-description { + padding: 16px; +} + +.example-element-description-attribution { + opacity: 0.5; +} + +.mat-column-edit, .mat-column-delete, .mat-column-expand { + width: 32px; +} + +.long-form { + width: 100%; +} + +.mat-error { + color: red; +} + +.warning-icon { + margin-right: 5px; +} + +.reference-editor, .template-editor { + width: 50%; +} diff --git a/src/app/editor/gamesystem-editor/template-gamesystem-editor/template-state-editor/template-state-editor.component.spec.ts b/src/app/editor/gamesystem-editor/template-gamesystem-editor/template-state-editor/template-state-editor.component.spec.ts new file mode 100644 index 0000000..b3e2605 --- /dev/null +++ b/src/app/editor/gamesystem-editor/template-gamesystem-editor/template-state-editor/template-state-editor.component.spec.ts @@ -0,0 +1,23 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { TemplateStateEditorComponent } from './template-state-editor.component'; + +describe('TemplateStateEditorComponent', () => { + let component: TemplateStateEditorComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + imports: [TemplateStateEditorComponent] + }) + .compileComponents(); + + fixture = TestBed.createComponent(TemplateStateEditorComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/editor/gamesystem-editor/template-gamesystem-editor/template-state-editor/template-state-editor.component.ts b/src/app/editor/gamesystem-editor/template-gamesystem-editor/template-state-editor/template-state-editor.component.ts new file mode 100644 index 0000000..dfab3fc --- /dev/null +++ b/src/app/editor/gamesystem-editor/template-gamesystem-editor/template-state-editor/template-state-editor.component.ts @@ -0,0 +1,65 @@ +import {Component, Input, ViewChild} from '@angular/core'; +import {SimpleState} from "../../../../project/game-model/gamesystems/states/SimpleState"; +import {TemplateGamesystem} from "../../../../project/game-model/gamesystems/TemplateGamesystem"; +import {SimpleStateEditorComponent} from "../../state-editor/simple-state-editor/simple-state-editor.component"; +import {animate, state, style, transition, trigger} from "@angular/animations"; +import {ScriptAccount} from "../../../../project/game-model/scriptAccounts/ScriptAccount"; +import {MatTableDataSource} from "@angular/material/table"; +import {ScriptAccountCondition} from "../../../../project/game-model/gamesystems/conditions/ScriptAccountCondition"; + +@Component({ + selector: 'app-template-state-editor', + templateUrl: './template-state-editor.component.html', + styleUrl: './template-state-editor.component.scss', + animations: [ + trigger('detailExpand', [ + state('collapsed,void', style({height: '0px', minHeight: '0'})), + state('expanded', style({height: '*'})), + transition('expanded <=> collapsed', animate('225ms cubic-bezier(0.4, 0.0, 0.2, 1)')), + ]), + ], +}) +export class TemplateStateEditorComponent { + + @Input() templateGamesystem: TemplateGamesystem | undefined + @Input() scriptAccounts: ScriptAccount[] = [] + + dataSource = new MatTableDataSource(); + displayedColumns = ["name", "initial", "edit", "delete"]; + columnsToDisplayWithExpand = [...this.displayedColumns, 'expand']; + expandedElement: SimpleState | null = null; + editedElement: SimpleState | null = null; + + editedStateLabelError: boolean = false; + + onExtractReferenceState(state: SimpleState) { + this.templateGamesystem!.addReferenceState(state) + this.dataSource.data = this.templateGamesystem!.templateStates + } + + applyFilter(event: KeyboardEvent) { + const filterValue = (event.target as HTMLInputElement).value; + this.dataSource.filter = filterValue.trim().toLowerCase(); + } + + onCreateCondition(state: SimpleState, $event: ScriptAccountCondition) { + + } + + onEditState(state: SimpleState) { + if(this.editedElement == null) { + this.editedElement = state + } else { + this.editedElement = null + } + } + + onDeleteState(state: SimpleState) { + this.templateGamesystem!.templateStates = this.templateGamesystem!.templateStates.filter(templateState => templateState.stateLabel !== state.stateLabel) + this.dataSource.data = this.templateGamesystem!.templateStates + } + + deleteCondition(state: SimpleState, $event: ScriptAccountCondition) { + + } +} diff --git a/src/app/project/game-model/gamesystems/TemplateGamesystem.ts b/src/app/project/game-model/gamesystems/TemplateGamesystem.ts new file mode 100644 index 0000000..a7d6ff3 --- /dev/null +++ b/src/app/project/game-model/gamesystems/TemplateGamesystem.ts @@ -0,0 +1,22 @@ +import {SimpleGamesystem} from "./SimpleGamesystem"; +import {TemplateState} from "./states/TemplateState"; +import {SimpleState} from "./states/SimpleState"; +import {ScriptAccountCondition} from "./conditions/ScriptAccountCondition"; + +export class TemplateGamesystem { + referenceGamesystem: SimpleGamesystem + + templateStates: SimpleState[] = [] + + + constructor(referenceGamesystem: SimpleGamesystem) { + this.referenceGamesystem = referenceGamesystem; + } + + addReferenceState(referenceState: SimpleState) { + const templateState = new SimpleState(referenceState.stateLabel, referenceState.stateDescription); + templateState.conditions = referenceState.conditions.map(condition => + ScriptAccountCondition.constructScriptAccountCondition(condition.scriptAccount, condition.minValue, condition.maxValue)!) + this.templateStates.push(templateState) + } +} diff --git a/src/app/project/game-model/gamesystems/states/TemplateState.ts b/src/app/project/game-model/gamesystems/states/TemplateState.ts new file mode 100644 index 0000000..d0c0caa --- /dev/null +++ b/src/app/project/game-model/gamesystems/states/TemplateState.ts @@ -0,0 +1,14 @@ +import {Transition} from "../transitions/Transition"; +import {SimpleState} from "./SimpleState"; +import {ScriptAccountCondition} from "../conditions/ScriptAccountCondition"; + +export class TemplateState { + referenceState: SimpleState + conditions: ScriptAccountCondition[] + + + constructor(referenceState: SimpleState, conditions: ScriptAccountCondition[]) { + this.referenceState = referenceState; + this.conditions = conditions; + } +}