diff --git a/newton/app.js b/newton/app.js index 76370db..c5f98da 100644 --- a/newton/app.js +++ b/newton/app.js @@ -1,10 +1,11 @@ -const { BrowserWindow } = require('electron'); -const path = require('node:path'); +const { BrowserWindow } = require('electron'); +const path = require('node:path'); -const { menu } = require('./menu'); -const { argsParser } = require('./args-parser'); +const { menu } = require('./menu'); +const { systemTray } = require('./system-tray'); +const { argsParser } = require('./args-parser'); const { settingsManager } = require('./settings-manager'); -const { newtonFs } = require('./fs'); +const { newtonFs } = require('./fs'); const BASE_PATH = '../build/app'; @@ -47,6 +48,7 @@ const createWindow = (startType = "build", debug = false, args = []) => { }); menu.load(win); + systemTray.load(menu.menuStruct); // win.setAutoHideMenuBar(true) diff --git a/newton/fs.js b/newton/fs.js index 7eefacb..70c7927 100644 --- a/newton/fs.js +++ b/newton/fs.js @@ -1,7 +1,8 @@ const { dialog } = require('electron'); -const path = require('node:path'); -const fs = require('node:fs'); -const os = require('os') +const path = require('node:path'); +const fs = require('node:fs'); +const os = require('os') +const chokidar = require('chokidar'); diff --git a/newton/system-tray.js b/newton/system-tray.js new file mode 100644 index 0000000..e9a79c5 --- /dev/null +++ b/newton/system-tray.js @@ -0,0 +1,49 @@ +const { Tray, Menu } = require('electron') +const { newtonFs } = require('./fs'); + + + +const load = (win) => { + let trayIcon = new Tray( newtonFs.getIconPath() ); + + const trayMenuTemplate = [ + { + label: "File", + submenu: [ + { + label: 'New', + click: () => win.webContents.send('menu-actions', "new-file") + }, { + label: 'Open', + click: () => win.webContents.send('menu-actions', "open-files") + }, { + label: 'save', + click: () => win.webContents.send('menu-actions', "save-file") + }, { + label: 'Save As', + click: () => win.webContents.send('menu-actions', "save-file-as") + }, { + label: 'Terminal', + click: () => {} + } + ] + }, { + label: 'Settings', + click: () => win.webContents.send('menu-actions', "open-settings") + }, { + label: 'Help', + click: () => win.webContents.send('menu-actions', "show-about") + } + ]; + + trayIcon.setContextMenu( + Menu.buildFromTemplate(trayMenuTemplate) + ); +} + + +module.exports = { + systemTray: { + load: load, + } +}; \ No newline at end of file diff --git a/package.json b/package.json index 6639892..06a53c2 100644 --- a/package.json +++ b/package.json @@ -54,6 +54,7 @@ "ace-linters": "1.5.3", "bootstrap": "5.3.6", "bootstrap-icons": "1.12.1", + "chokidar": "4.0.3", "express": "4.18.2", "rxjs": "7.8.0", "tslib": "2.3.0", @@ -68,8 +69,8 @@ "@types/jasmine": "5.1.0", "@types/node": "18.18.0", "concurrently": "9.1.2", - "electron-builder": "26.0.12", "electron": "36.2.0", + "electron-builder": "26.0.12", "electron-reloader": "1.2.3", "jasmine-core": "5.6.0", "karma": "6.4.0", diff --git a/src/app/editor/editors.component.ts b/src/app/editor/editors.component.ts index b45c825..6bbcc63 100644 --- a/src/app/editor/editors.component.ts +++ b/src/app/editor/editors.component.ts @@ -4,7 +4,7 @@ import { Subject, takeUntil } from 'rxjs'; import { EditSession } from 'ace-builds'; import { getModeForPath } from 'ace-builds/src-noconflict/ext-modelist'; -import { AceEditorComponent } from "./ace/ace-editor.component"; +import { NewtonEditorComponent } from "./newton-editor/newton-editor.component"; import { EditorsService } from '../common/services/editor/editors.service'; import { TabsService } from '../common/services/editor/tabs/tabs.service'; @@ -31,7 +31,7 @@ export class EditorsComponent { private unsubscribe = new Subject(); @ViewChild('containerRef', {read: ViewContainerRef}) containerRef!: ViewContainerRef; - editors: Map>; + editors: Map>; editorSettings: typeof EditorSettings; files: Map; activeEditor!: string; @@ -43,7 +43,7 @@ export class EditorsComponent { private tabsService: TabsService ) { this.editorSettings = EditorSettings; - this.editors = new Map>(); + this.editors = new Map>(); this.files = new Map(); } @@ -141,6 +141,8 @@ export class EditorsComponent { case "zoom-out": editorComponent.zoomOut() break; + case "open-settings": + editor.showSettingsMenu(); case "show-about": break; default: @@ -155,7 +157,7 @@ export class EditorsComponent { } private createEditor() { - const component = this.containerRef.createComponent(AceEditorComponent); + const component = this.containerRef.createComponent(NewtonEditorComponent); component.instance.editorSettings = this.editorSettings; this.editors.set(component.instance.uuid, component) diff --git a/src/app/editor/ace/ace-editor.base.ts b/src/app/editor/newton-editor/newton-editor.base.ts similarity index 96% rename from src/app/editor/ace/ace-editor.base.ts rename to src/app/editor/newton-editor/newton-editor.base.ts index 6c27a4e..893b9c0 100644 --- a/src/app/editor/ace/ace-editor.base.ts +++ b/src/app/editor/newton-editor/newton-editor.base.ts @@ -7,7 +7,7 @@ import { NewtonFile } from '../../common/types/file.type'; @Directive() -export class AceEditorBase { +export class NewtonEditorBase { @ViewChild('editor') editorElm!: ElementRef; @Input() editorSettings!: typeof EditorSettings; editor!: any; @@ -32,6 +32,10 @@ export class AceEditorBase { this.editorElm.nativeElement.classList.remove("active-editor") } + public commander() { + this.editor.execCommand("openCommandPalette"); + } + protected search() { console.log(this.editor.session.getMode()["$id"]); } diff --git a/src/app/editor/ace/ace-editor.component.css b/src/app/editor/newton-editor/newton-editor.component.css similarity index 100% rename from src/app/editor/ace/ace-editor.component.css rename to src/app/editor/newton-editor/newton-editor.component.css diff --git a/src/app/editor/ace/ace-editor.component.html b/src/app/editor/newton-editor/newton-editor.component.html similarity index 100% rename from src/app/editor/ace/ace-editor.component.html rename to src/app/editor/newton-editor/newton-editor.component.html diff --git a/src/app/editor/ace/ace-editor.component.ts b/src/app/editor/newton-editor/newton-editor.component.ts similarity index 88% rename from src/app/editor/ace/ace-editor.component.ts rename to src/app/editor/newton-editor/newton-editor.component.ts index 60fe7d8..69ad9d9 100644 --- a/src/app/editor/ace/ace-editor.component.ts +++ b/src/app/editor/newton-editor/newton-editor.component.ts @@ -2,30 +2,32 @@ import { Component } from "@angular/core"; // Import Ace and its modes/themes so that `ace` global is defined import * as ace from "ace-builds/src-noconflict/ace"; +import "ace-builds/src-noconflict/ext-settings_menu"; +import "ace-builds/src-noconflict/ext-command_bar"; +import "ace-builds/src-noconflict/ext-language_tools"; import "ace-builds/src-noconflict/theme-one_dark"; import "ace-builds/src-noconflict/theme-dracula"; -import "ace-builds/src-noconflict/ext-language_tools"; import { InfoBarService } from '../../common/services/editor/info-bar/info-bar.service'; import { EditorsService } from '../../common/services/editor/editors.service'; import { LSPService } from '../../common/services/lsp.service'; -import { AceEditorBase } from './ace-editor.base'; +import { NewtonEditorBase } from './newton-editor.base'; @Component({ - selector: 'ace-editor', + selector: 'newton-editor', standalone: true, imports: [ ], - templateUrl: './ace-editor.component.html', - styleUrl: './ace-editor.component.css', + templateUrl: './newton-editor.component.html', + styleUrl: './newton-editor.component.css', host: { 'class': 'col' } }) -export class AceEditorComponent extends AceEditorBase { +export class NewtonEditorComponent extends NewtonEditorBase { constructor( @@ -52,7 +54,14 @@ export class AceEditorComponent extends AceEditorBase { this.editor.setOptions( this.editorSettings.CONFIG ); // this.editor.commands.addCommands( this.editorSettings.KEYBINDINGS ); this.editor.commands.addCommands([ - { + { + name: "openCommandPalette2", + bindKey: {linux: "Command-Shift-/|F1", win: "Ctrl-Shift-/|F1"}, + exec: () => { + this.commander(); + }, + readOnly: false + }, { name: "search", bindKey: {win: "ctrl-f", mac: "ctrl-f"}, exec: () => { @@ -142,6 +151,10 @@ export class AceEditorComponent extends AceEditorBase { // Note: https://ajaxorg.github.io/ace-api-docs/interfaces/ace.Ace.EditorEvents.html + this.editor.on("changeStatus", (e) => { + console.log(e); + }); + this.editor.on("click", () => { this.updateInfoBar(); }); diff --git a/src/assets/css/ace-overrides.css b/src/assets/css/ace-overrides.css index 7619370..0be79dc 100644 --- a/src/assets/css/ace-overrides.css +++ b/src/assets/css/ace-overrides.css @@ -2,6 +2,20 @@ /* IDs */ +#ace_settingsmenu, #kbshortcutmenu { + background-color: rgba(0, 0, 0, 0.0); + color: rgba(255, 255, 255, 1.0); + box-shadow: -1px 4px 5px rgba(124, 124, 124, 0.64); + padding: 1em 0.5em 2em 1em; + overflow: auto; + position: absolute; + margin: 0; + bottom: 0; + right: 0; + top: 0; + z-index: 9991; + cursor: default; +} /* CLASSES */ @@ -13,6 +27,23 @@ background-color: #25282c !important; } +.ace_editor.ace_autocomplete { + width: 300px; + z-index: 200000; + border: 1px lightgray solid; + position: fixed; + box-shadow: 2px 3px 5px rgba(0,0,0,.2); + line-height: 1.4; + background-color: rgba(0, 0, 0, 0.0); + color: rgba(255, 255, 255, 1.0); +} + +.ace_selected { + background: rgba(249, 148, 6, 0.64); + color: rgba(0, 0, 0, 1.0); + /* color: rgba(255, 255, 255, 1.0); */ +} + .ace_sb-v, .ace_sb-h { width: 0.8em !important;