From db1d4a9a37f32359e202f40a2c93306725ae7dcd Mon Sep 17 00:00:00 2001 From: itdominator <1itdominator@gmail.com> Date: Sat, 8 Nov 2025 01:04:33 -0600 Subject: [PATCH] Added right click options to tabs bar --- src/app/editor/tabs/tabs.component.css | 22 +++- src/app/editor/tabs/tabs.component.html | 16 ++- src/app/editor/tabs/tabs.component.ts | 132 +++++++++++++++++++++--- 3 files changed, 153 insertions(+), 17 deletions(-) diff --git a/src/app/editor/tabs/tabs.component.css b/src/app/editor/tabs/tabs.component.css index f4735ec..e83cfa6 100644 --- a/src/app/editor/tabs/tabs.component.css +++ b/src/app/editor/tabs/tabs.component.css @@ -45,6 +45,26 @@ align-self: center; } +.contextMenu { + display: inline-table; + z-index: 500; + position: absolute; + min-width: 2em; + padding: 0.2em; + top: 0em; + right: 0em; + background-color: gray; +} + +.contextMenu li:hover { + background-color: rgba(0, 124, 0, 0.64); + cursor: pointer; +} + +.contextMenu li { + padding: 0em 0.2em; +} + .close-button { background: rgba(116, 0, 0, 0.64); border-style: solid; @@ -54,4 +74,4 @@ .close-button:hover { background: rgba(256, 0, 0, 0.64); -} \ No newline at end of file +} diff --git a/src/app/editor/tabs/tabs.component.html b/src/app/editor/tabs/tabs.component.html index 52998c7..ec9becc 100644 --- a/src/app/editor/tabs/tabs.component.html +++ b/src/app/editor/tabs/tabs.component.html @@ -3,7 +3,7 @@ cdkDropListLockAxis="x" cdkDropListOrientation="horizontal" (cdkDropListDropped)="dropped($event)" - (click)="handleAction($event)" + (mousedown)="handleAction($event)" class="display-contents" > @@ -19,4 +19,16 @@ - \ No newline at end of file + + + \ No newline at end of file diff --git a/src/app/editor/tabs/tabs.component.ts b/src/app/editor/tabs/tabs.component.ts index 2506b8f..e76103d 100644 --- a/src/app/editor/tabs/tabs.component.ts +++ b/src/app/editor/tabs/tabs.component.ts @@ -2,6 +2,8 @@ import { Component, ChangeDetectorRef, DestroyRef, + ElementRef, + ViewChild, inject } from '@angular/core'; import { CommonModule } from '@angular/common'; @@ -12,6 +14,8 @@ import { TabsService } from '../../common/services/editor/tabs/tabs.service'; import { ServiceMessage } from '../../common/types/service-message.type'; +import { ButtonMap } from '../../common/constants/button.map'; + @Component({ @@ -34,7 +38,11 @@ export class TabsComponent { private tabsService: TabsService = inject(TabsService); private changeDetectorRef: ChangeDetectorRef = inject(ChangeDetectorRef); + @ViewChild('contextMenu') contextMenu!: ElementRef; + public showContextMenu: boolean = false; + tabs: any[] = this.tabsService.tabs; + targetEvent!: any; constructor() { @@ -74,23 +82,41 @@ export class TabsComponent { protected handleAction(event: any): void { let target = event.target; - if ( target.classList.contains("tab") ) { - this.tabsService.sendEditorsServiceAMessage( - "set-tab-to-editor", - event.srcElement.getAttribute("title") - ); + if (ButtonMap.RIGHT === event.button) { + let menuElm = this.contextMenu.nativeElement; + let pageX = event.clientX; + let pageY = event.clientY; - } else if ( target.classList.contains("title") ) { - this.tabsService.sendEditorsServiceAMessage( - "set-tab-to-editor", - event.srcElement.parentElement.getAttribute("title") - ); - } else if ( target.classList.contains("close-button") ) { - this.tabsService.closeTab( - event.srcElement.parentElement.getAttribute("title") - ); + const origin = { + left: pageX + 5, + top: pageY - 5 + }; + + menuElm.style.left = `${origin.left}px`; + menuElm.style.top = `${origin.top}px`; + this.showContextMenu = true; + + this.targetEvent = event; + return; } + this.showContextMenu = false; + this.processTargetEvent(event); + } + + public hideContextMenu() { + this.showContextMenu = false; + } + + public contextMenuClicked(event: any) { + this.showContextMenu = false; + + const command = event.target.getAttribute("command"); + const args = event.target.getAttribute("args"); + + if (!command) return; + + this[command]( (args) ? args : null ); } public createTab(title: string, uuid: string, path: string): void { @@ -117,4 +143,82 @@ export class TabsComponent { this.tabsService.move(event.previousIndex); } + + private close(event: any): void { + this.tabsService.closeTab( + this.targetEvent.srcElement.parentElement.getAttribute("title") + ); + } + + private closeAll(event: any): void { + let elm = this.targetEvent.srcElement.parentElement; + let startElm = elm; + + // clear right + while (elm) { + elm = elm.nextSibling; + if (!elm || elm.nodeType == 8) continue; + + this.tabsService.closeTab( elm.getAttribute("title") ); + } + + // clear left + elm = startElm; + while (elm) { + elm = elm.previousSibling; + if (!elm || elm.nodeType == 8) continue; + + this.tabsService.closeTab( elm.getAttribute("title") ); + } + + // clear initial target + elm = startElm; + this.tabsService.closeTab( elm.getAttribute("title") ); + } + + private closeAllLeft(event: any): void { + let elm = this.targetEvent.srcElement.parentElement; + + // clear left + while (elm) { + elm = elm.previousSibling; + if (!elm || elm.nodeType == 8) continue; + + this.tabsService.closeTab( elm.getAttribute("title") ); + } + } + + private closeAllRight(event: any): void { + let elm = this.targetEvent.srcElement.parentElement; + + // clear right + while (elm) { + elm = elm.nextSibling; + if (!elm || elm.nodeType == 8) continue; + + this.tabsService.closeTab( elm.getAttribute("title") ); + } + } + + private processTargetEvent(event: any): void { + let target = event.target; + + if ( target.classList.contains("tab") ) { + this.tabsService.sendEditorsServiceAMessage( + "set-tab-to-editor", + event.srcElement.getAttribute("title") + ); + + } else if ( target.classList.contains("title") ) { + this.tabsService.sendEditorsServiceAMessage( + "set-tab-to-editor", + event.srcElement.parentElement.getAttribute("title") + ); + } else if ( target.classList.contains("close-button") ) { + this.tabsService.closeTab( + event.srcElement.parentElement.getAttribute("title") + ); + } + } + } \ No newline at end of file