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