From ae6c21f8ad4270c19b14ec0a27b2497471c919c9 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 --- .../services/color-tokenizer.service.ts | 2 +- src/app/editor/tabs/tabs.component.css | 22 ++- src/app/editor/tabs/tabs.component.html | 17 ++- src/app/editor/tabs/tabs.component.ts | 140 ++++++++++++++++-- 4 files changed, 161 insertions(+), 20 deletions(-) diff --git a/src/app/common/services/color-tokenizer.service.ts b/src/app/common/services/color-tokenizer.service.ts index ea778d5..30205b5 100644 --- a/src/app/common/services/color-tokenizer.service.ts +++ b/src/app/common/services/color-tokenizer.service.ts @@ -47,7 +47,7 @@ export class ColorTokenizerService { ); } - console.log(this.cssLines); + // console.log(this.cssLines); } public parseLine(line: string): {} | null { 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..acc7afa 100644 --- a/src/app/editor/tabs/tabs.component.html +++ b/src/app/editor/tabs/tabs.component.html @@ -3,7 +3,8 @@ cdkDropListLockAxis="x" cdkDropListOrientation="horizontal" (cdkDropListDropped)="dropped($event)" - (click)="handleAction($event)" + (mousedown)="handleActionMouseDown($event)" + (click)="handleActionClick($event)" class="display-contents" > @@ -19,4 +20,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..4150208 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() { @@ -71,26 +79,48 @@ export class TabsComponent { }); } - protected handleAction(event: any): void { + protected handleActionClick(event: any): void { + if (ButtonMap.RIGHT === event.button) return; + let target = event.target; - if ( target.classList.contains("tab") ) { - this.tabsService.sendEditorsServiceAMessage( - "set-tab-to-editor", - event.srcElement.getAttribute("title") - ); + this.showContextMenu = false; + this.processTargetEvent(event); + } - } 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") - ); - } + protected handleActionMouseDown(event: any): void { + if (ButtonMap.LEFT === event.button) return; + let target = event.target; + + let menuElm = this.contextMenu.nativeElement; + let pageX = event.clientX; + let pageY = event.clientY; + + const origin = { + left: pageX + 5, + top: pageY - 5 + }; + + menuElm.style.left = `${origin.left}px`; + menuElm.style.top = `${origin.top}px`; + this.targetEvent = event; + this.showContextMenu = true; + } + + 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 +147,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