most menu events mapped; cleanup
This commit is contained in:
parent
fbf6933102
commit
ae43722881
101
app.js
101
app.js
@ -1,4 +1,4 @@
|
|||||||
const { BrowserWindow } = require('electron');
|
const { BrowserWindow, Menu } = require('electron');
|
||||||
const path = require('node:path');
|
const path = require('node:path');
|
||||||
const fs = require('node:fs');
|
const fs = require('node:fs');
|
||||||
const os = require('os')
|
const os = require('os')
|
||||||
@ -28,7 +28,9 @@ const createWindow = (startType = "build", debug = false, args = []) => {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// win.removeMenu()
|
setupMenu(win);
|
||||||
|
|
||||||
|
// win.setAutoHideMenuBar(true)
|
||||||
|
|
||||||
if (debug == true) {
|
if (debug == true) {
|
||||||
win.webContents.openDevTools();
|
win.webContents.openDevTools();
|
||||||
@ -45,7 +47,102 @@ const createWindow = (startType = "build", debug = false, args = []) => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const setupMenu = (win) => {
|
||||||
|
const menu = Menu.buildFromTemplate([
|
||||||
|
{
|
||||||
|
label: "File",
|
||||||
|
submenu: [
|
||||||
|
{
|
||||||
|
label: 'New',
|
||||||
|
click: () => win.webContents.send('menu-actions', "new-file")
|
||||||
|
}, {
|
||||||
|
label: 'Open',
|
||||||
|
click: () => win.webContents.send('load-files', [path.join(__dirname, `${BASE_PATH}/index.html`)])
|
||||||
|
}, {
|
||||||
|
label: 'Terminal',
|
||||||
|
click: () => {}
|
||||||
|
}, {
|
||||||
|
label: 'save',
|
||||||
|
click: () => win.webContents.send('menu-actions', "save-file")
|
||||||
|
}, {
|
||||||
|
label: 'Save As',
|
||||||
|
click: () => win.webContents.send('menu-actions', "save-file-as")
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}, {
|
||||||
|
label: "Edit",
|
||||||
|
submenu: [
|
||||||
|
{
|
||||||
|
label: 'Undo',
|
||||||
|
click: () => win.webContents.send('menu-actions', "undo")
|
||||||
|
}, {
|
||||||
|
label: 'Redo',
|
||||||
|
click: () => win.webContents.send('menu-actions', "redo")
|
||||||
|
}, {
|
||||||
|
label: 'Cut',
|
||||||
|
click: () => win.webContents.send('menu-actions', "cut")
|
||||||
|
}, {
|
||||||
|
label: 'Copy',
|
||||||
|
click: () => win.webContents.send('menu-actions', "copy")
|
||||||
|
}, {
|
||||||
|
label: 'Paste',
|
||||||
|
click: () => win.webContents.send('menu-actions', "paste")
|
||||||
|
|
||||||
|
}, {
|
||||||
|
label: 'Delete',
|
||||||
|
click: () => win.webContents.send('menu-actions', "delete")
|
||||||
|
}, {
|
||||||
|
label: 'Select All',
|
||||||
|
click: () => win.webContents.send('menu-actions', "select-all")
|
||||||
|
}, {
|
||||||
|
label: 'Indent',
|
||||||
|
click: () => win.webContents.send('menu-actions', "blockindent")
|
||||||
|
}, {
|
||||||
|
label: 'De-Indent',
|
||||||
|
click: () => win.webContents.send('menu-actions', "blockoutdent")
|
||||||
|
}, {
|
||||||
|
label: 'To Upper Case',
|
||||||
|
click: () => win.webContents.send('menu-actions', "touppercase")
|
||||||
|
}, {
|
||||||
|
label: 'To Lower Case',
|
||||||
|
click: () => win.webContents.send('menu-actions', "tolowercase")
|
||||||
|
},
|
||||||
|
]
|
||||||
|
}, {
|
||||||
|
label: "View",
|
||||||
|
submenu: [
|
||||||
|
{
|
||||||
|
label: 'Zoom In',
|
||||||
|
click: () => win.webContents.send('menu-actions', "zoom-in")
|
||||||
|
}, {
|
||||||
|
label: 'Zoom Out',
|
||||||
|
click: () => win.webContents.send('menu-actions', "zoom-out")
|
||||||
|
}, {
|
||||||
|
label: 'Toggle Full Screen',
|
||||||
|
click: () => { win.setFullScreen(!win.fullScreen) }
|
||||||
|
}, {
|
||||||
|
label: 'Toggle Developer Tools',
|
||||||
|
click: () => win.webContents.toggleDevTools()
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}, {
|
||||||
|
label: "Help",
|
||||||
|
submenu: [
|
||||||
|
{
|
||||||
|
label: 'About',
|
||||||
|
click: () => win.webContents.send('menu-actions', "show-about")
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
|
||||||
|
]);
|
||||||
|
|
||||||
|
Menu.setApplicationMenu(menu)
|
||||||
|
}
|
||||||
|
|
||||||
const getFileContents = (_path, useRelativePath = false) => {
|
const getFileContents = (_path, useRelativePath = false) => {
|
||||||
|
console.log(`Getting Contents For: ${_path}`);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
if (!useRelativePath) {
|
if (!useRelativePath) {
|
||||||
return fs.readFileSync(_path, 'utf8');
|
return fs.readFileSync(_path, 'utf8');
|
||||||
|
29
main.js
29
main.js
@ -4,7 +4,7 @@ try {
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
const { app, ipcMain } = require('electron');
|
const { app, ipcMain, dialog } = require('electron');
|
||||||
const { newton } = require('./app');
|
const { newton } = require('./app');
|
||||||
const path = require('node:path');
|
const path = require('node:path');
|
||||||
const fs = require('node:fs');
|
const fs = require('node:fs');
|
||||||
@ -42,9 +42,36 @@ const loadArgs = () => {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const saveFile = (path, content) => {
|
||||||
|
console.log("...");
|
||||||
|
}
|
||||||
|
|
||||||
|
const saveFileAs = (content) => {
|
||||||
|
console.log(content);
|
||||||
|
dialog.showSaveDialog((fileName) => {
|
||||||
|
console.log(fileName);
|
||||||
|
|
||||||
|
if (fileName === undefined){
|
||||||
|
console.log("You didn't save the file");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// fileName is a string that contains the path and filename created in the save file dialog.
|
||||||
|
fs.writeFile(fileName, content, (err) => {
|
||||||
|
if(err){
|
||||||
|
alert("An error ocurred creating the file "+ err.message)
|
||||||
|
}
|
||||||
|
|
||||||
|
alert("The file has been succesfully saved");
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
const loadHandlers = () => {
|
const loadHandlers = () => {
|
||||||
ipcMain.handle('getLspConfigData', (eve) => newton.getLspConfigData());
|
ipcMain.handle('getLspConfigData', (eve) => newton.getLspConfigData());
|
||||||
ipcMain.handle('getFileContents', (eve, file) => newton.getFileContents(file));
|
ipcMain.handle('getFileContents', (eve, file) => newton.getFileContents(file));
|
||||||
|
ipcMain.handle('saveFile', (eve, path, content) => saveFile(path, "Some text to save into the file"));
|
||||||
|
ipcMain.handle('saveFileAs', (eve, content) => saveFileAs("Some text to save into the file"));
|
||||||
}
|
}
|
||||||
|
|
||||||
app.whenReady().then(() => {
|
app.whenReady().then(() => {
|
||||||
|
@ -6,9 +6,15 @@ contextBridge.exposeInMainWorld('electron', {
|
|||||||
chrome: () => process.versions.chrome,
|
chrome: () => process.versions.chrome,
|
||||||
electron: () => process.versions.electron,
|
electron: () => process.versions.electron,
|
||||||
});
|
});
|
||||||
|
contextBridge.exposeInMainWorld('main', {
|
||||||
|
onMenuActions: (callback) => ipcRenderer.on('menu-actions', (_event, action) => callback(action)),
|
||||||
|
});
|
||||||
|
|
||||||
contextBridge.exposeInMainWorld('fs', {
|
contextBridge.exposeInMainWorld('fs', {
|
||||||
getLspConfigData: () => ipcRenderer.invoke("getLspConfigData"),
|
getLspConfigData: () => ipcRenderer.invoke("getLspConfigData"),
|
||||||
getFileContents: (file) => ipcRenderer.invoke("getFileContents", file),
|
getFileContents: (file) => ipcRenderer.invoke("getFileContents", file),
|
||||||
getPathForFile: (file) => webUtils.getPathForFile(file)
|
saveFile: (path, content) => ipcRenderer.invoke("saveFile", path, content),
|
||||||
|
saveFileAs: (content) => ipcRenderer.invoke("saveFileAs", content),
|
||||||
|
getPathForFile: (file) => webUtils.getPathForFile(file),
|
||||||
|
onLoadFiles: (callback) => ipcRenderer.on('load-files', (_event, files) => callback(files)),
|
||||||
});
|
});
|
||||||
|
@ -13,10 +13,16 @@ declare global {
|
|||||||
chrome: () => Promise<string>,
|
chrome: () => Promise<string>,
|
||||||
electron: () => Promise<string>,
|
electron: () => Promise<string>,
|
||||||
},
|
},
|
||||||
|
main: {
|
||||||
|
onMenuActions: (arg0: any) => Promise<string>,
|
||||||
|
},
|
||||||
fs: {
|
fs: {
|
||||||
getLspConfigData: () => Promise<string>,
|
getLspConfigData: () => Promise<string>,
|
||||||
getFileContents: (arg0: any) => Promise<string>,
|
getFileContents: (arg0: any) => Promise<string>,
|
||||||
|
saveFile: (arg0: any, arg1: any) => Promise<string>,
|
||||||
|
saveFileAs: (arg0: any) => Promise<string>,
|
||||||
getPathForFile: any,
|
getPathForFile: any,
|
||||||
|
onLoadFiles: (arg0: any) => Promise<string>,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -15,15 +15,15 @@ export const EditorSettings: any = {
|
|||||||
enableSnippets: true,
|
enableSnippets: true,
|
||||||
highlightActiveLine: true,
|
highlightActiveLine: true,
|
||||||
enableMultiselect: true,
|
enableMultiselect: true,
|
||||||
tabSize: 4,
|
|
||||||
useSoftTabs: true,
|
useSoftTabs: true,
|
||||||
|
tabSize: 4,
|
||||||
|
navigateWithinSoftTabs: true,
|
||||||
tooltipFollowsMouse: true,
|
tooltipFollowsMouse: true,
|
||||||
wrapBehavioursEnabled: false,
|
wrapBehavioursEnabled: false,
|
||||||
scrollPastEnd: 0.5,
|
scrollPastEnd: 0.5,
|
||||||
mergeUndoDeltas: false,
|
mergeUndoDeltas: false,
|
||||||
showGutter: true,
|
showGutter: true,
|
||||||
customScrollbar: true,
|
customScrollbar: true,
|
||||||
navigateWithinSoftTabs: true,
|
|
||||||
scrollSpeed: 5
|
scrollSpeed: 5
|
||||||
}
|
}
|
||||||
};
|
};
|
@ -50,7 +50,7 @@ export class LSPService {
|
|||||||
private getLanguageProviderWithClientServer(mode: string) {
|
private getLanguageProviderWithClientServer(mode: string) {
|
||||||
let _initializationOptions = {};
|
let _initializationOptions = {};
|
||||||
|
|
||||||
if (Object.keys(this.lspConfigData).length !== 0) {
|
if ( Object.keys(this.lspConfigData).length !== 0 && this.lspConfigData[mode] ) {
|
||||||
_initializationOptions = this.lspConfigData[mode]["initialization-options"];
|
_initializationOptions = this.lspConfigData[mode]["initialization-options"];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -10,7 +10,6 @@ export class AceEditorBase {
|
|||||||
@Input() editorSettings!: typeof EditorSettings;
|
@Input() editorSettings!: typeof EditorSettings;
|
||||||
editor!: any;
|
editor!: any;
|
||||||
uuid!: string;
|
uuid!: string;
|
||||||
fontSize: number = 12;
|
|
||||||
cutBuffer: string = "";
|
cutBuffer: string = "";
|
||||||
timerId: number = -1;
|
timerId: number = -1;
|
||||||
|
|
||||||
@ -19,18 +18,51 @@ export class AceEditorBase {
|
|||||||
) {}
|
) {}
|
||||||
|
|
||||||
|
|
||||||
|
protected search() {
|
||||||
|
console.log(this.editor.getSession()["$modeId"])
|
||||||
|
}
|
||||||
|
|
||||||
|
protected saveFile() {
|
||||||
|
const text = this.editor.session.getValue();
|
||||||
|
// window.fs.saveFile(text);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected saveFileAs() {
|
||||||
|
const text = this.editor.session.getValue();
|
||||||
|
window.fs.saveFileAs(text);
|
||||||
|
}
|
||||||
|
|
||||||
protected zoomIn() {
|
protected zoomIn() {
|
||||||
this.fontSize += 1;
|
this.editor.setFontSize(
|
||||||
this.editorElm.nativeElement.style.fontSize = `${this.fontSize}px`;
|
parseInt(this.editor.getFontSize()) + 1
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
protected zoomOut() {
|
protected zoomOut() {
|
||||||
this.fontSize -= 1;
|
this.editor.setFontSize(
|
||||||
this.editorElm.nativeElement.style.fontSize = `${this.fontSize}px`;
|
parseInt(this.editor.getFontSize()) - 1
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
protected search() {
|
protected cutText() {
|
||||||
console.log(this.editor.getSession()["$modeId"])
|
let cutText = this.editor.getSelectedText();
|
||||||
|
this.editor.remove();
|
||||||
|
navigator.clipboard.writeText(cutText).catch(() => {
|
||||||
|
console.error("Unable to cut text...");
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
protected copyText() {
|
||||||
|
let copyText = this.editor.getSelectedText();
|
||||||
|
navigator.clipboard.writeText(copyText).catch(() => {
|
||||||
|
console.error("Unable to copy text...");
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
protected pasteText() {
|
||||||
|
navigator.clipboard.readText().then((pasteText) => {
|
||||||
|
this.editor.insert(pasteText, true);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
protected movelinesUp() {
|
protected movelinesUp() {
|
||||||
@ -51,17 +83,15 @@ export class AceEditorBase {
|
|||||||
const cursorPosition = this.editor.getCursorPosition();
|
const cursorPosition = this.editor.getCursorPosition();
|
||||||
let lineText = this.editor.session.getLine(cursorPosition.row);
|
let lineText = this.editor.session.getLine(cursorPosition.row);
|
||||||
this.cutBuffer += `${lineText}\n`;
|
this.cutBuffer += `${lineText}\n`;
|
||||||
this.editor.session.removeFullLines(cursorPosition.row, cursorPosition.row)
|
|
||||||
|
|
||||||
|
this.editor.session.removeFullLines(cursorPosition.row, cursorPosition.row)
|
||||||
this.setBufferClearTimeout();
|
this.setBufferClearTimeout();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected pasteCutBuffer() {
|
protected pasteCutBuffer() {
|
||||||
if (this.timerId) { clearTimeout(this.timerId); }
|
if (this.timerId) { clearTimeout(this.timerId); }
|
||||||
|
|
||||||
const cursorPosition = this.editor.getCursorPosition();
|
this.editor.insert(this.cutBuffer, true);
|
||||||
this.editor.session.insert(cursorPosition, this.cutBuffer)
|
|
||||||
|
|
||||||
this.setBufferClearTimeout();
|
this.setBufferClearTimeout();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -109,6 +109,20 @@ export class AceEditorComponent extends AceEditorBase {
|
|||||||
this.editor.session.destroy();
|
this.editor.session.destroy();
|
||||||
},
|
},
|
||||||
readOnly: true
|
readOnly: true
|
||||||
|
}, {
|
||||||
|
name: "saveFile",
|
||||||
|
bindKey: {win: "ctrl-s", mac: "ctrl-s"},
|
||||||
|
exec: () => {
|
||||||
|
this.saveFile();
|
||||||
|
},
|
||||||
|
readOnly: true
|
||||||
|
}, {
|
||||||
|
name: "saveFileAs",
|
||||||
|
bindKey: {win: "ctrl-shift-s", mac: "ctrl-shift-s"},
|
||||||
|
exec: () => {
|
||||||
|
this.saveFileAs();
|
||||||
|
},
|
||||||
|
readOnly: true
|
||||||
}
|
}
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
@ -51,8 +51,9 @@ export class EditorsComponent {
|
|||||||
|
|
||||||
public ngAfterViewInit(): void {
|
public ngAfterViewInit(): void {
|
||||||
this.loadSubscribers();
|
this.loadSubscribers();
|
||||||
|
this.loadMainSubscribers();
|
||||||
|
|
||||||
let editor = this.createEditor();
|
let editor = this.createEditor();
|
||||||
this.activeEditor = editor.instance.uuid;
|
this.activeEditor = editor.instance.uuid;
|
||||||
this.createEditor();
|
this.createEditor();
|
||||||
}
|
}
|
||||||
@ -65,6 +66,55 @@ export class EditorsComponent {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
loadMainSubscribers() {
|
||||||
|
window.fs.onLoadFiles(async (paths: []) => {
|
||||||
|
for (let i = 0; i < paths.length; i++) {
|
||||||
|
let file = new File([], "") as NewtonFile;
|
||||||
|
|
||||||
|
await this.addFile(paths[i], file);
|
||||||
|
this.addTab(file);
|
||||||
|
}
|
||||||
|
|
||||||
|
let session = this.files.get(paths[ paths.length - 1 ]).session;
|
||||||
|
this.setSession(session);
|
||||||
|
});
|
||||||
|
|
||||||
|
window.main.onMenuActions(async (action: string) => {
|
||||||
|
let editorComponent = this.getActiveEditorComponent();
|
||||||
|
let editor = editorComponent.editor;
|
||||||
|
|
||||||
|
switch ( action ) {
|
||||||
|
case "new-file":
|
||||||
|
break;
|
||||||
|
case "save-file":
|
||||||
|
editorComponent.saveFile();
|
||||||
|
break;
|
||||||
|
case "save-file-as":
|
||||||
|
editorComponent.saveFileAs();
|
||||||
|
break;
|
||||||
|
case "cut":
|
||||||
|
editorComponent.cutText();
|
||||||
|
break;
|
||||||
|
case "copy":
|
||||||
|
editorComponent.copyText();
|
||||||
|
break;
|
||||||
|
case "paste":
|
||||||
|
editorComponent.pasteText();
|
||||||
|
break;
|
||||||
|
case "zoom-in":
|
||||||
|
editorComponent.zoomIn()
|
||||||
|
break;
|
||||||
|
case "zoom-out":
|
||||||
|
editorComponent.zoomOut()
|
||||||
|
break;
|
||||||
|
case "show-about":
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
editor.execCommand(action);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
ngOnDestroy() {
|
ngOnDestroy() {
|
||||||
this.unsubscribe.next();
|
this.unsubscribe.next();
|
||||||
this.unsubscribe.complete();
|
this.unsubscribe.complete();
|
||||||
@ -79,16 +129,36 @@ export class EditorsComponent {
|
|||||||
return component;
|
return component;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected onFileDropped(event: any) {
|
protected onFileDropped(files: any) {
|
||||||
this.loadFilesList(event).then((session: EditSession | undefined | null) => {
|
this.loadFilesList(files).then((session: EditSession | undefined | null) => {
|
||||||
if ( !session ) return;
|
this.setSession(session);
|
||||||
|
|
||||||
let editorComponent = this.editors.get(this.activeEditor)?.instance;
|
|
||||||
let editor = editorComponent.editor;
|
|
||||||
editor?.setSession(session);
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private async setSession(session: EditSession | undefined | null) {
|
||||||
|
if ( !session ) return;
|
||||||
|
|
||||||
|
let editor = this.getActiveEditor();
|
||||||
|
editor?.setSession(session);
|
||||||
|
}
|
||||||
|
|
||||||
|
private getSession() {
|
||||||
|
let editorComponent = this.editors.get(this.activeEditor)?.instance;
|
||||||
|
let editor = editorComponent.editor;
|
||||||
|
|
||||||
|
return editor?.getSession();
|
||||||
|
}
|
||||||
|
|
||||||
|
private getActiveEditorComponent(): any {
|
||||||
|
return this.editors.get(this.activeEditor)?.instance;
|
||||||
|
}
|
||||||
|
|
||||||
|
private getActiveEditor(): any {
|
||||||
|
let editorComponent = this.editors.get(this.activeEditor)?.instance;
|
||||||
|
let editor = editorComponent.editor;
|
||||||
|
return editor;
|
||||||
|
}
|
||||||
|
|
||||||
private async loadFilesList(files: Array<NewtonFile>): Promise<EditSession | undefined | null> {
|
private async loadFilesList(files: Array<NewtonFile>): Promise<EditSession | undefined | null> {
|
||||||
for (let i = 0; i < files.length; i++) {
|
for (let i = 0; i < files.length; i++) {
|
||||||
const file = files[i];
|
const file = files[i];
|
||||||
@ -104,7 +174,7 @@ export class EditorsComponent {
|
|||||||
return files[ files.length - 1 ].session;
|
return files[ files.length - 1 ].session;
|
||||||
}
|
}
|
||||||
|
|
||||||
private async addFile(path: string, file: NewtonFile) {
|
private async addFile(path: string, file: NewtonFile): Promise<void> {
|
||||||
try {
|
try {
|
||||||
let pathParts = path.split("/");
|
let pathParts = path.split("/");
|
||||||
file.fname = pathParts[ pathParts.length - 1 ];
|
file.fname = pathParts[ pathParts.length - 1 ];
|
||||||
|
Loading…
Reference in New Issue
Block a user