diff --git a/src/app/common/directives/draggable.directive.ts b/src/app/common/directives/draggable.directive.ts index 9ae68af..40cf789 100644 --- a/src/app/common/directives/draggable.directive.ts +++ b/src/app/common/directives/draggable.directive.ts @@ -22,6 +22,7 @@ export class DraggableDirective { @HostListener('pointerdown', ['$event']) onPointerDown(event: PointerEvent): void { console.log("pointerdown"); + this.dragging = true; this.dragStart.emit(event); } @@ -31,14 +32,12 @@ export class DraggableDirective { if (!this.dragging) return; console.log("pointermove"); - this.dragging = true; this.dragMove.emit(event); } @HostListener('document:pointerup', ['$event']) onPointerUp(event: PointerEvent): void { if (!this.dragging) return; - console.log("pointerup"); this.dragging = false; diff --git a/src/app/common/directives/pane-handle.directive.ts b/src/app/common/directives/pane-handle.directive.ts new file mode 100644 index 0000000..79f8b4f --- /dev/null +++ b/src/app/common/directives/pane-handle.directive.ts @@ -0,0 +1,82 @@ +import { + Directive, + Output, + EventEmitter, + HostListener +} from '@angular/core'; + + + +@Directive({ + selector: '[pane-handle]' +}) +export class PaneHandleDirective { + @Output() dragStart = new EventEmitter(); + @Output() dragMove = new EventEmitter(); + @Output() dragEnd = new EventEmitter(); + + private dragging: boolean = false; + private isHrPane: boolean = false; + private parentElm: any; + private leftSiblingElm: any; + private rightSiblingElm: any; + + + @HostListener('pointerdown', ['$event']) + onPointerDown(event: PointerEvent): void { + event.preventDefault(); + + let target = event.target as Element; + if ( + !target.classList.contains("hr-pane-handle") && + !target.classList.contains("vr-pane-handle") + ) { + console.log("Must have 'hr-pane-handle' or 'vr-pane-handle' in classList!"); + return; + } + + target.requestPointerLock(); + + this.dragging = true; + this.isHrPane = ( target.classList.contains("hr-pane-handle") ) ? true : false ; + this.parentElm = target.parentElement as Element; + this.leftSiblingElm = target.previousElementSibling as Element; + this.rightSiblingElm = target.nextElementSibling as Element; + + this.dragStart.emit(event); + } + + @HostListener('pointermove', ['$event']) + onPointerMove(event: PointerEvent): void { + if (!this.dragging) return; + + let x = event.movementX; + let y = event.movementY; + let parentBounds = this.parentElm.getBoundingClientRect(); + let leftBounds = this.leftSiblingElm.getBoundingClientRect(); + let rightBounds = this.rightSiblingElm.getBoundingClientRect(); + + if (this.isHrPane) { + this.leftSiblingElm.style.height = `${leftBounds.height + y}px`; + this.rightSiblingElm.style.height = `${rightBounds.height - y}px`; + } else { + this.leftSiblingElm.style.width = `${leftBounds.width + x}px`; + this.rightSiblingElm.style.width = `${rightBounds.width - x}px`; + } + + this.dragMove.emit(event); + } + + @HostListener('pointerup', ['$event']) + onPointerUp(event: PointerEvent): void { + if (!this.dragging) return; + + this.dragging = false; + this.leftSiblingElm = null; + this.rightSiblingElm = null; + + document.exitPointerLock(); + this.dragEnd.emit(event); + } + +} \ No newline at end of file diff --git a/src/app/common/services/editor/editors.service.ts b/src/app/common/services/editor/editors.service.ts index ac6baa1..fdcbd36 100644 --- a/src/app/common/services/editor/editors.service.ts +++ b/src/app/common/services/editor/editors.service.ts @@ -1,4 +1,4 @@ -import { ComponentRef, Injectable } from '@angular/core'; +import { Injectable } from '@angular/core'; import { ReplaySubject, Observable } from 'rxjs'; import { NewtonEditorComponent } from "../../../editor/newton-editor/newton-editor.component"; @@ -16,7 +16,7 @@ import { NewtonFile } from '../../types/file.type'; export class EditorsService { private messageSubject: ReplaySubject = new ReplaySubject(1); - editors: Map>; + editors: Map; editorSettings: typeof EditorSettings; activeEditor!: string; @@ -24,24 +24,42 @@ export class EditorsService { constructor() { this.editorSettings = EditorSettings; - this.editors = new Map>(); + this.editors = new Map(); } - public getEditorsAsArray(): ComponentRef[] { + public getEditorsAsArray(): NewtonEditorComponent[] { return [...this.editors.values()]; } public get(uuid: string): NewtonEditorComponent { - return this.editors.get(uuid).instance; + return this.editors.get(uuid); } - public set(uuid: string, component: ComponentRef) { + public set(uuid: string, component: NewtonEditorComponent) { this.editors.set(uuid, component); + + if (Object.keys(this.editors).length < 1) return; + + let leftEditor = null; + let rightEditor = null; + let _editors = this.getEditorsAsArray(); + + for (let i = 0; i < _editors.length; i++) { + if (_editors[i].uuid !== uuid) continue; + + leftEditor = _editors[i - 1]; + rightEditor = _editors[i]; + + } + + leftEditor.rightSiblingUUID = rightEditor.uuid; + rightEditor.leftSiblingUUID = leftEditor.uuid; } public async setSession(file: NewtonFile | undefined | null) { if ( !file ) return; + let editorComponent = this.getActiveEditorComponent(); let editor = editorComponent.editor; diff --git a/src/app/editor/editor-resize/editor-resize.component.css b/src/app/editor/editor-resize/editor-resize.component.css deleted file mode 100644 index c682ff9..0000000 --- a/src/app/editor/editor-resize/editor-resize.component.css +++ /dev/null @@ -1,16 +0,0 @@ -.editor-size-button { - text-align: center; - width: 4em; - color: rgba(225, 225, 225, 0.64); - border-style: solid; - border-width: thin; - border-color: rgba(124, 124, 124, 0.64); - margin-left: 0.2em; - margin-right: 0.2em; - float: left; -} - -.editor-size-button:hover { - cursor: pointer; - border-color: rgba(0, 124, 0, 0.64); -} \ No newline at end of file diff --git a/src/app/editor/editor-resize/editor-resize.component.html b/src/app/editor/editor-resize/editor-resize.component.html deleted file mode 100644 index 11fd385..0000000 --- a/src/app/editor/editor-resize/editor-resize.component.html +++ /dev/null @@ -1,28 +0,0 @@ -
-
- 100% -
-
- 75% -
-
- 50% -
-
- 25% -
-
-
-
- 100% -
-
- 75% -
-
- 50% -
-
- 25% -
-
diff --git a/src/app/editor/editor-resize/editor-resize.component.ts b/src/app/editor/editor-resize/editor-resize.component.ts deleted file mode 100644 index aee3769..0000000 --- a/src/app/editor/editor-resize/editor-resize.component.ts +++ /dev/null @@ -1,84 +0,0 @@ -import { Component, inject } from '@angular/core'; - -import { EditorsService } from '../../common/services/editor/editors.service'; - - - -@Component({ - selector: 'editor-resize', - standalone: true, - imports: [ - ], - templateUrl: './editor-resize.component.html', - styleUrl: './editor-resize.component.css', - host: { - 'class': 'row' - } -}) -export class EditorResizeComponent { - - private editorsService: EditorsService = inject(EditorsService); - - - constructor() { - } - - - // Note: Only really works with 2 editors and very brittle logic. - protected setEditorSize(event: any) { - let lEditorComponent = null; - let rEditorComponent = null; - let lSize = 6; - let rSize = 6; - - if ( - event.target.parentElement.classList.contains("editor-left-size") - ) { - lSize = parseInt( - event.target.classList[1].split("-")[1] - ); - rSize = 12 - lSize; - - lEditorComponent = this.editorsService.getActiveEditorComponent(); - if (lEditorComponent.leftSiblingUUID) { - rEditorComponent = lEditorComponent; - lEditorComponent = this.editorsService.get(lEditorComponent.leftSiblingUUID); - } else { - rEditorComponent = this.editorsService.get(lEditorComponent.rightSiblingUUID); - } - } else { - rSize = parseInt( - event.target.classList[1].split("-")[1] - ); - lSize = 12 - rSize; - rEditorComponent = this.editorsService.getActiveEditorComponent(); - if (rEditorComponent.rightSiblingUUID) { - lEditorComponent = rEditorComponent; - rEditorComponent = this.editorsService.get(rEditorComponent.rightSiblingUUID); - } else { - lEditorComponent = this.editorsService.get(rEditorComponent.leftSiblingUUID); - } - } - - this.resizeAndFocus(lEditorComponent, lSize, rEditorComponent, rSize); - } - - private resizeAndFocus(lEditorComponent: any, lSize: number, rEditorComponent: any, rSize: number) { - let lElm = lEditorComponent.editorElm.nativeElement.parentElement; - let rElm = rEditorComponent.editorElm.nativeElement.parentElement; - - lElm.setAttribute( - 'class', - (lSize == 0) ? "hidden" : `col col-${lSize}` - ); - - rElm.setAttribute( - 'class', - (rSize == 0) ? "hidden" : `col col-${rSize}` - ); - - if (lSize == 0) rEditorComponent.editor.focus(); - if (rSize == 0) lEditorComponent.editor.focus(); - } - -} \ No newline at end of file diff --git a/src/app/editor/editors.component.css b/src/app/editor/editors.component.css index 7b00dfa..4f620fa 100644 --- a/src/app/editor/editors.component.css +++ b/src/app/editor/editors.component.css @@ -1,3 +1,3 @@ .dropzone { - height: 90vh; -} + height: 92vh; +} \ No newline at end of file diff --git a/src/app/editor/editors.component.html b/src/app/editor/editors.component.html index 1ae7612..67d416d 100644 --- a/src/app/editor/editors.component.html +++ b/src/app/editor/editors.component.html @@ -1,10 +1,9 @@
- - + +
+
- -
\ No newline at end of file diff --git a/src/app/editor/editors.component.ts b/src/app/editor/editors.component.ts index 309a1c3..4e4e469 100644 --- a/src/app/editor/editors.component.ts +++ b/src/app/editor/editors.component.ts @@ -1,14 +1,14 @@ -import { Component, ViewChild, ViewContainerRef, inject } from '@angular/core'; +import { Component, inject } from '@angular/core'; import { Subject, takeUntil } from 'rxjs'; -import { NewtonEditorComponent } from "./newton-editor/newton-editor.component"; -import { EditorResizeComponent } from "./editor-resize/editor-resize.component"; - import { EditorsService } from '../common/services/editor/editors.service'; import { TabsService } from '../common/services/editor/tabs/tabs.service'; import { FilesService } from '../common/services/editor/files.service'; +import { NewtonEditorComponent } from "./newton-editor/newton-editor.component"; + import { DndDirective } from '../common/directives/dnd.directive'; +import { PaneHandleDirective } from '../common/directives/pane-handle.directive'; import { NewtonFile } from '../common/types/file.type'; import { ServiceMessage } from '../common/types/service-message.type'; @@ -19,7 +19,8 @@ import { ServiceMessage } from '../common/types/service-message.type'; standalone: true, imports: [ DndDirective, - EditorResizeComponent + PaneHandleDirective, + NewtonEditorComponent ], templateUrl: './editors.component.html', styleUrl: './editors.component.css', @@ -34,8 +35,6 @@ export class EditorsComponent { private tabsService: TabsService = inject(TabsService); private filesService: FilesService = inject(FilesService); - @ViewChild('containerRef', {read: ViewContainerRef}) containerRef!: ViewContainerRef; - constructor() { } @@ -44,14 +43,6 @@ export class EditorsComponent { private ngAfterViewInit(): void { this.loadSubscribers(); this.loadMainSubscribers(); - - let leftEditor = this.createEditor(); - let rightEditor = this.createEditor(); - - this.editorsService.setActiveEditor(leftEditor.instance.uuid); - leftEditor.instance.isDefault = true; - leftEditor.instance.rightSiblingUUID = rightEditor.instance.uuid; - rightEditor.instance.leftSiblingUUID = leftEditor.instance.uuid; } private ngOnDestroy() { @@ -120,7 +111,7 @@ export class EditorsComponent { let editors = this.editorsService.getEditorsAsArray(); for (let i = 0; i < editors.length; i++) { - let editorComponent = editors[i].instance; + let editorComponent = editors[i]; if (editorComponent.editor.session == file.session) { editorComponent.newSession(); } @@ -225,14 +216,6 @@ export class EditorsComponent { }); } - private createEditor() { - const component = this.containerRef.createComponent(NewtonEditorComponent); - component.instance.editorSettings = this.editorsService.editorSettings; - this.editorsService.set(component.instance.uuid, component) - - return component; - } - protected onFileDropped(files: any) { this.filesService.loadFilesList(files).then((file: NewtonFile | undefined | null) => { this.editorsService.setSession(file); diff --git a/src/app/editor/newton-editor/newton-editor.base.ts b/src/app/editor/newton-editor/newton-editor.base.ts index 0f41a80..3a0e306 100644 --- a/src/app/editor/newton-editor/newton-editor.base.ts +++ b/src/app/editor/newton-editor/newton-editor.base.ts @@ -16,8 +16,8 @@ import { ServiceMessage } from '../../common/types/service-message.type'; @Directive() export class NewtonEditorBase { - public uuid: string = uuid.v4();; - public isDefault: boolean = false; + public uuid: string = uuid.v4(); + @Input() public isDefault: boolean = false; public leftSiblingUUID!: string; public rightSiblingUUID!: string; diff --git a/src/app/editor/newton-editor/newton-editor.component.ts b/src/app/editor/newton-editor/newton-editor.component.ts index 93487fd..955878c 100644 --- a/src/app/editor/newton-editor/newton-editor.component.ts +++ b/src/app/editor/newton-editor/newton-editor.component.ts @@ -26,7 +26,8 @@ import { ServiceMessage } from '../../common/types/service-message.type'; templateUrl: './newton-editor.component.html', styleUrl: './newton-editor.component.css', host: { - 'class': 'col col-6' +// 'class': 'col col-6' + 'style': 'width: 48%;' } }) export class NewtonEditorComponent extends NewtonEditorBase { @@ -34,11 +35,14 @@ export class NewtonEditorComponent extends NewtonEditorBase { constructor() { super(); + + this.editorsService.set(this.uuid, this); } private ngAfterViewInit(): void { if (this.isDefault) { + this.editorsService.setActiveEditor(this.uuid); this.addActiveStyling(); } @@ -52,6 +56,8 @@ export class NewtonEditorComponent extends NewtonEditorBase { } private configAceAndBindToElement(): void { + this.editorSettings = this.editorsService.editorSettings; + ace.config.set('basePath', this.editorSettings.BASE_PATH); this.editor = ace.edit( this.editorElm.nativeElement ); diff --git a/src/assets/css/styles.css b/src/assets/css/styles.css index fb14ed2..31516f5 100644 --- a/src/assets/css/styles.css +++ b/src/assets/css/styles.css @@ -36,6 +36,24 @@ body { margin-right: 0.2em; } +.hr-pane-handle, +.vr-pane-handle { + border: 2px dashed lightblue; +} + +/* +.hr-pane-handle { +} + +.vr-pane-handle { + transform: rotate(90deg); +} +*/ + +.vr-pane-handle { + max-width: 0.05em; +} +