init commit

master
叶志超 2023-10-13 16:39:27 +08:00
parent 09fd8d57c4
commit c1fc36b44c
28 changed files with 786 additions and 0 deletions

81
src/main/app.ts Normal file
View File

@ -0,0 +1,81 @@
import { app, BrowserWindow } from 'electron'
import { MainWindow } from './window/localSoftware/MainWindow'
app.commandLine.appendSwitch('enable-features', 'ElectronSerialChooser')
let mainWindow: MainWindow | null = null
const createMainWindow = () => {
mainWindow = new MainWindow()
mainWindow.webContents.session.on('select-serial-port', (event, portList, webContents, callback) => {
//Add listeners to handle ports being added or removed before the callback for `select-serial-port`
//is called.
// mainWindow.webContents.session.on('serial-port-added', (event, port) => {
// console.log('serial-port-added FIRED WITH', port)
// //Optionally update portList to add the new port
// })
// mainWindow.webContents.session.on('serial-port-removed', (event, port) => {
// console.log('serial-port-removed FIRED WITH', port)
// //Optionally update portList to remove the port
// })
event.preventDefault()
if (portList && portList.length > 0) {
mainWindow?.setSelectedPort(portList[0])
callback(portList[0].portId)
} else {
callback('') //Could not find any matching devices
}
})
mainWindow.webContents.session.setPermissionCheckHandler((webContents, permission, requestingOrigin, details) => {
if (permission === 'serial') {
return true
}
return false
})
mainWindow.webContents.session.setDevicePermissionHandler((details) => {
if (details.deviceType === 'serial') {
return true
}
return false
})
}
const gotTheLock = app.requestSingleInstanceLock()
if (!gotTheLock) {
app.quit()
} else {
app.on('second-instance', () => {
// 有人试图运行第二个实例,我们应该关注我们的窗口
if (mainWindow) {
if (mainWindow.isMinimized()) mainWindow.restore()
mainWindow.focus()
}
})
// 创建 mainWindow, 加载应用的其余部分, etc...
app.once('ready', createMainWindow)
app.on('window-all-closed', () => {
if (process.platform !== 'darwin') app.quit()
})
app.on('activate', () => {
if (BrowserWindow.getAllWindows().length === 0) createMainWindow()
})
}
export const quit = () => app.quit()
// if (process.env.NODE_ENV != 'development') {
// app.once('browser-window-created', enableAutoLaunch)
// }

27
src/main/index.ts Normal file
View File

@ -0,0 +1,27 @@
import { join } from 'path'
import { app, ipcMain, BrowserWindow } from 'electron'
const IS_DEV_ENV = process.env.NODE_ENV === 'development'
const ROOT_PATH = IS_DEV_ENV ? 'http://localhost:5173' : `file://${__dirname}/../render`
const preload = IS_DEV_ENV ? join(__dirname, './preload.ts') : join(__dirname, './preload.js')
let mainWindow : BrowserWindow;
const createMainWindow = () => {
mainWindow = new BrowserWindow({
width: 900,
height: 600,
webPreferences: {
nodeIntegration: true,
preload: join(__dirname, './preload.js'),
},
})
mainWindow.loadURL(join(ROOT_PATH, 'page/index.html'))
}
ipcMain.on("CLOSE_MAIN_WINDOW", () => {
app.quit()
})
app.on('ready', createMainWindow)

31
src/main/preload.js Normal file
View File

@ -0,0 +1,31 @@
const { ipcRenderer, contextBridge } = require('electron')
contextBridge.exposeInMainWorld('ipcRenderer', {
send: (channel, data) => {
// whitelist channels
let validChannels = ['toMain']
if (validChannels.includes(channel)) {
ipcRenderer.send(channel, data)
}
ipcRenderer.send(channel, data)
},
sendSync: (channel, data) => {
// whitelist channels
let validChannels = ['toMain']
if (validChannels.includes(channel)) {
return ipcRenderer.sendSync(channel, data)
}
return ipcRenderer.sendSync(channel, data)
},
receive: (channel, func) => {
let validChannels = ['fromMain']
if (validChannels.includes(channel)) {
// Deliberately strip event as it includes `sender`
ipcRenderer.on(channel, (event, ...args) => func(...args))
}
ipcRenderer.on(channel, (event, ...args) => func(...args))
},
unreceive: (channel) => {
ipcRenderer.removeAllListeners(channel)
}
})

View File

@ -0,0 +1,30 @@
import { join } from 'path'
import { Menu, BrowserWindow } from 'electron'
Menu.setApplicationMenu(null)
// TODO: 修改标题栏ico图标
const BASE_WINDOW_OPTIONS = {
icon: join(__dirname, '../../../public/favicon.ico'),
webPreferences : {
nodeIntegration : true,
enableBlinkFeatures: 'Serial',
experimentalFeatures: true,
preload : join(__dirname, '../preload.js')
},
}
export abstract class BaseWindow extends BrowserWindow {
constructor (options = {}) {
Object.assign(options, BASE_WINDOW_OPTIONS)
super(options)
this.bindIpcEvent()
if (process.env.NODE_ENV === 'development') {
this.webContents.openDevTools()
}
}
bindIpcEvent() {}
}

View File

@ -0,0 +1,13 @@
import { join } from 'path'
import { BaseWindow } from './BaseWindow'
const IS_DEV_ENV = process.env.NODE_ENV === 'development'
const ROOT_PATH = IS_DEV_ENV ? 'http://localhost:5173/page' : `file://${__dirname}/../../render/page`
export abstract class LocalSoftwareWindow extends BaseWindow {
constructor (localFileName: string, options = {}) {
super(options)
this.loadURL(join(ROOT_PATH, localFileName))
}
}

View File

@ -0,0 +1,24 @@
import { BaseWindow } from './BaseWindow'
import { BrowserWindow } from 'electron'
// TODO: 禁止双击标题栏改变窗口大小
const MODEL_WINDOW_OPTIONS = {
modal : true,
show : false,
movable : false,
resizable : false,
minimizable : false,
maximizable : false,
}
export abstract class ModelWindow extends BaseWindow {
constructor (parent: BrowserWindow | null, options = {}) {
Object.assign(options, { parent }, MODEL_WINDOW_OPTIONS)
super(options)
this.maximize()
this.once('ready-to-show', () => {
this.show()
})
}
}

View File

@ -0,0 +1,9 @@
import { BaseWindow } from './BaseWindow'
export class OnlineSoftwareWindow extends BaseWindow {
constructor (url: string, options = {}) {
super(options)
this.loadURL(url)
}
}

View File

@ -0,0 +1,7 @@
import { LocalSoftwareWindow } from '../LocalSoftwareWindow'
export class BDAndTimeWindow extends LocalSoftwareWindow {
constructor (options = {}) {
super('BD&time.html', options )
}
}

View File

@ -0,0 +1,7 @@
import { LocalSoftwareWindow } from '../LocalSoftwareWindow'
export class BDCommunicationAssistantWindow extends LocalSoftwareWindow {
constructor (options = {}) {
super('BD-communication-assistant.html', options)
}
}

View File

@ -0,0 +1,7 @@
import { LocalSoftwareWindow } from '../LocalSoftwareWindow'
export class BDComprehensiveExperimentalPlatformWindow extends LocalSoftwareWindow {
constructor (options = {}) {
super('BD-comprehensive-experimental-platform.html', options)
}
}

View File

@ -0,0 +1,7 @@
import { LocalSoftwareWindow } from '../LocalSoftwareWindow'
export class BDDataAnalysisPlatformWindow extends LocalSoftwareWindow {
constructor (options = {}) {
super('BD-data-analysis-platform.html', options)
}
}

View File

@ -0,0 +1,7 @@
import { LocalSoftwareWindow } from '../LocalSoftwareWindow'
export class BDMeteorologicalDataDisplayPlatformWindow extends LocalSoftwareWindow {
constructor (options = {}) {
super('BD-meteorological-data-display-platform.html', options )
}
}

View File

@ -0,0 +1,7 @@
import { LocalSoftwareWindow } from '../LocalSoftwareWindow'
export class BDMeteorologicalDataProtocolWindow extends LocalSoftwareWindow {
constructor (options = {}) {
super('BD-meteorological-data-protocol.html', options )
}
}

View File

@ -0,0 +1,35 @@
import { LocalSoftwareWindow } from '../LocalSoftwareWindow'
import { IpcMainEvent } from 'electron'
import { readFile } from 'fs'
import { usedSync } from 'windows-drive-letters'
export class BDPositionTrackRetracingWindow extends LocalSoftwareWindow {
constructor (options = {}) {
super('BD-position-track-retracing.html', options)
}
bindIpcEvent() {
this.webContents.ipc.on('GET_DATA', this.getData )
}
getData(event: IpcMainEvent) {
const letters = usedSync()
const filePath = letters[letters.length - 1] + ':/BDLOG.TXT'
readFile(filePath, 'utf8', (err, data) => {
if (err) {
if (err.code === 'ENOENT') {
console.error('file not exist')
event.returnValue = { err: new Error('文件不存在') }
return
}
console.error(err, 'open')
event.returnValue = { err }
return
}
event.returnValue = { data }
})
}
}

View File

@ -0,0 +1,7 @@
import { LocalSoftwareWindow } from '../LocalSoftwareWindow'
export class BDSatellite3DPostureDisplayWindow extends LocalSoftwareWindow {
constructor (options = {}) {
super('BD-satellite-3D-posture-display.html', options)
}
}

View File

@ -0,0 +1,7 @@
import { LocalSoftwareWindow } from '../LocalSoftwareWindow'
export class BDSatelliteAttitudeControlWindow extends LocalSoftwareWindow {
constructor (options = {}) {
super('BD-satellite-attitude-control.html', options)
}
}

View File

@ -0,0 +1,7 @@
import { LocalSoftwareWindow } from '../LocalSoftwareWindow'
export class BDSatelliteParameterMonitoringPlatformWindow extends LocalSoftwareWindow {
constructor (options = {}) {
super('BD-satellite-parameter-monitoring-platform.html', options)
}
}

View File

@ -0,0 +1,7 @@
import { LocalSoftwareWindow } from '../LocalSoftwareWindow'
export class BDSatelliteTimeConfigurationWindow extends LocalSoftwareWindow {
constructor (options = {}) {
super('BD-satellite-time-configuration.html', options)
}
}

View File

@ -0,0 +1,7 @@
import { LocalSoftwareWindow } from '../LocalSoftwareWindow'
export class ClockConfigWindow extends LocalSoftwareWindow {
constructor (options = {}) {
super('clock-config.html', options )
}
}

View File

@ -0,0 +1,7 @@
import { LocalSoftwareWindow } from '../LocalSoftwareWindow'
export class DistanceCalculationToolWindow extends LocalSoftwareWindow {
constructor (options = {}) {
super('distance-calculation-tool.html', options )
}
}

View File

@ -0,0 +1,7 @@
import { LocalSoftwareWindow } from '../LocalSoftwareWindow'
export class ElectronicScreenDesignWindow extends LocalSoftwareWindow {
constructor (options = {}) {
super('electronic-screen-design.html', options )
}
}

View File

@ -0,0 +1,46 @@
import { readFile, writeFile, existsSync } from 'fs'
import { IpcMainEvent } from 'electron'
import { LocalSoftwareWindow } from '../LocalSoftwareWindow'
const FONT_LIBRARY_FILE_PATH = './fontLibrary.json'
export class FontDesignWindow extends LocalSoftwareWindow {
constructor (options = {}) {
super('font-design.html', options )
}
bindIpcEvent(): void {
this.webContents.ipc.on('LOAD_FONT_LIBRARY', this.load )
this.webContents.ipc.on('SAVE_FONT_LIBRARY', this.save )
}
load(event: IpcMainEvent) {
if (!existsSync(FONT_LIBRARY_FILE_PATH)) {
event.returnValue = {}
return
}
readFile(FONT_LIBRARY_FILE_PATH, 'utf8', (err, data) => {
if (err) {
console.error(err);
event.returnValue = {}
} else {
event.returnValue = { data }
}
})
}
save(event: IpcMainEvent, fontLibrary: string) {
if (!fontLibrary) {
event.returnValue = { err: new Error('字库为空') }
return
}
try {
writeFile( FONT_LIBRARY_FILE_PATH, fontLibrary, 'utf8', () => event.returnValue = 'OK')
} catch (err) {
event.returnValue = { err }
}
}
}

View File

@ -0,0 +1,7 @@
import { LocalSoftwareWindow } from '../LocalSoftwareWindow'
export class GeneratingConstellationChartWindow extends LocalSoftwareWindow {
constructor (options = {}) {
super('generating-constellation-chart.html', options )
}
}

View File

@ -0,0 +1,7 @@
import { LocalSoftwareWindow } from '../LocalSoftwareWindow'
export class GestureRecognitionWindow extends LocalSoftwareWindow {
constructor (options = {}) {
super('gesture-recognition.html', options )
}
}

View File

@ -0,0 +1,364 @@
import { BrowserWindow, IpcMainEvent, SerialPort } from 'electron'
import { exec, execFile, spawn } from 'child_process'
import { join } from 'path'
import { existsSync } from 'fs'
import { LocalSoftwareWindow } from '../LocalSoftwareWindow'
import { OnlineSoftwareWindow } from '../OnlineSoftwareWindow'
import { BDAndTimeWindow } from './BDAndTimeWindow'
import { BDCommunicationAssistantWindow } from './BDCommunicationAssistantWindow'
import { BDComprehensiveExperimentalPlatformWindow } from './BDComprehensiveExperimentalPlatformWindow'
import { BDDataAnalysisPlatformWindow } from './BDDataAnalysisPlatformWindow'
import { BDPositionTrackRetracingWindow } from './BDPositionTrackRetracingWindow'
import { BDSatellite3DPostureDisplayWindow } from './BDSatellite3DPostureDisplayWindow'
import { BDSatelliteAttitudeControlWindow } from './BDSatelliteAttitudeControlWindow'
import { BDSatelliteParameterMonitoringPlatformWindow } from './BDSatelliteParameterMonitoringPlatformWindow'
import { BDSatelliteTimeConfigurationWindow } from './BDSatelliteTimeConfigurationWindow'
import { VoltageMonitoringWindow } from './VoltageMonitoringWindow'
import { WirelessCommunicationModuleConfigurationWindow } from './WirelessCommunicationModuleConfigurationWindow'
import { BDMeteorologicalDataDisplayPlatformWindow } from './BDMeteorologicalDataDisplayPlatformWindow'
import { BDMeteorologicalDataProtocolWindow } from './BDMeteorologicalDataProtocolWindow'
import { ElectronicScreenDesignWindow } from './ElectronicScreenDesignWindow'
import { GestureRecognitionWindow } from './GestureRecognitionWindow'
import { ClockConfigWindow } from './ClockConfigWindow'
import { FontDesignWindow } from './FontDesignWindow'
import { NixieTubeConfigurationWindow } from './NixieTubeConfigurationWindow'
import { DistanceCalculationToolWindow } from './DistanceCalculationToolWindow'
import { GeneratingConstellationChartWindow } from './GeneratingConstellationChartWindow'
import { init, scan, connect, disconnect, getCurrentConnections, WiFiNetwork, ConnectionOpts } from 'node-wifi'
import { blockDevices } from 'systeminformation'
init({})
const is_development_env = process.env.NODE_ENV === 'development'
// TODO: 尝试使用import.meta.globEager遍历所有子窗口类
// const modules = import.meta.globEager('./modal/**/*.ts');
// console.log(modules, '---------------------');
// Object.keys(modules).forEach((key) => {
// const mod = modules[key].default || {};
// console.log(key, '---------------------');
// console.log(mod, '---------------------');
// // const modList = Array.isArray(mod) ? [...mod] : [mod];
// // routeModuleList.push(...modList);
// });
const MAIN_WINDOW_OPTIONS = {
alwaysOnTop : is_development_env ? false : true,
kiosk : is_development_env ? false : true,
frame : false,
fullscreen : true,
}
const MODAL_WINDOW_OPTIONS = {
modal : true,
show : false,
movable : false,
resizable : false,
minimizable : false,
maximizable : false,
}
const ESP32_ROOT_PATH = 'C:\\esp32\\'
const ESP_TOOL_PATH = ESP32_ROOT_PATH + 'esptool.exe'
const BOOT_APP0_BIN_PATH = ESP32_ROOT_PATH + 'boot_app0.bin'
const BOOT_LOADER_BIN_PATH = ESP32_ROOT_PATH + 'bootloader.bin'
const PARTITIONS_BIN_PATH = ESP32_ROOT_PATH + 'partitions.bin'
const BIN_FILE_ROOT_PATH = process.env.LOCALAPPDATA + '\\Arduino\\'
const SYSTEM_CONFIG_BAT_PATH = 'C:\\SystemConfig\\SystemConfig.bat'
export class MainWindow extends LocalSoftwareWindow {
subWindow : BrowserWindow | undefined
subWindowOptions: Object
selectedPort : SerialPort | undefined
constructor (options = {}) {
Object.assign(options, MAIN_WINDOW_OPTIONS)
super('index.html', options)
this.subWindowOptions = Object.assign({}, { parent: this }, MODAL_WINDOW_OPTIONS)
}
setSelectedPort(port: SerialPort): void {
if (!port) return
this.selectedPort = port
}
bindIpcEvent(): void {
this.webContents.ipc.on('QUIT' , this.quit.bind(this) )
this.webContents.ipc.on('REBOOT' , this.reboot )
this.webContents.ipc.on('SHUTDOWN' , this.shutdown )
this.webContents.ipc.on('SYSTEM_REPAIR' , this.systemRepair )
this.webContents.ipc.on('SOFTWARE_UPGRADE' , this.softwareUpgrade.bind(this) )
this.webContents.ipc.on('NETWORK_QUERY' , this.networkQuery )
this.webContents.ipc.on('NETWORK_CONNECT' , this.networkConnect )
this.webContents.ipc.on('NETWORK_DISCONNECT' , this.networkDisconnect )
this.webContents.ipc.on('BURN_PROGRAM' , this.burnProgram )
this.webContents.ipc.on('LAUNCH_ONLINE_SOFTWARE', this.launchOnlineSoftware.bind(this) )
this.webContents.ipc.on('LAUNCH_LOCAL_SOFTWARE' , this.launchLocalSoftware.bind(this) )
}
quit() {
this.close()
}
reboot() {
const command = exec('shutdown -r -t 00', function (err, stdout, stderr) {
if (err || stderr) {
console.error("shutdown failed" + err + stderr);
}
});
if (!command || !command.stdin) return
command.stdin.end();
command.on("close", function (code) {
console.log("shutdown", code);
});
}
shutdown() {
const command = exec('shutdown -s -t 00', function (err, stdout, stderr) {
if (err || stderr) {
console.error("shutdown failed" + err + stderr);
}
});
if (!command || !command.stdin) return
command.stdin.end();
command.on("close", function (code) {
console.log("shutdown", code);
});
}
async getLastestDriveIdentifier() {
const devices = await blockDevices()
return devices[devices.length - 1]?.identifier
}
async softwareUpgrade(event: IpcMainEvent) {
const identifier = await this.getLastestDriveIdentifier()
if (!identifier) {
event.returnValue = new Error('系统出错,请联系售后技术支持')
return
}
const software_upgrade_file_path = identifier + '\\SoftwareUpgrade\\SoftwareUpgrade.bat'
if (!existsSync(software_upgrade_file_path)) {
event.returnValue = new Error('软件升级文件缺失,请联系售后技术支持')
return
}
spawn('cmd.exe', ['/c', software_upgrade_file_path], { detached: true, shell: true })
event.returnValue = 'OK'
}
systemRepair(event: IpcMainEvent) {
if (!existsSync(SYSTEM_CONFIG_BAT_PATH)) {
event.returnValue = new Error('系统修复文件缺失,请联系售后技术支持')
return
}
spawn('cmd.exe', ['/c', SYSTEM_CONFIG_BAT_PATH], { detached: true, shell: true })
}
async networkQuery(event: IpcMainEvent) {
try {
const current: WiFiNetwork[] = await getCurrentConnections()
let networks: WiFiNetwork[] = await scan()
networks = networks.filter(network => network.ssid.trim().length > 0)
networks.sort( (a, b) => { return b.signal_level - a.signal_level })
if (current.length > 0) {
for (let index = 0; index < networks.length; index++) {
const network = networks[index]
if (network.ssid === current[0].ssid) {
networks.unshift(networks.splice(index, 1)[0])
break
}
}
}
event.returnValue = { current, networks }
} catch (error) {
event.returnValue = 'ERROR'
}
}
async networkConnect(event: IpcMainEvent, network: ConnectionOpts) {
try {
await connect(network)
event.returnValue = 'OK'
} catch (error) {
event.returnValue = error
}
}
async networkDisconnect(event: IpcMainEvent) {
try {
await disconnect()
event.returnValue = 'OK'
} catch (error) {
event.returnValue = 'ERROR'
}
}
burnProgram(event: IpcMainEvent, binFileName: string) {
if (!existsSync(ESP_TOOL_PATH) ||
!existsSync(BOOT_APP0_BIN_PATH) ||
!existsSync(BOOT_LOADER_BIN_PATH) ||
!existsSync(PARTITIONS_BIN_PATH)) {
event.sender.send('BURN_PROGRAM_FEEDBACK', { err: new Error('烧录工具缺失,请联系售后技术支持') } )
return
}
const bin_file_path = join(BIN_FILE_ROOT_PATH, binFileName)
if (!existsSync(bin_file_path)) {
event.sender.send('BURN_PROGRAM_FEEDBACK', { err: new Error('程序文件缺失,请联系售后技术支持') } )
return
}
const mainWindow: MainWindow = BrowserWindow.fromWebContents(event.sender) as MainWindow
if (!mainWindow) {
event.sender.send('BURN_PROGRAM_FEEDBACK', { err: new Error('请先连接核心处理模块') } )
return
}
// 参考1https://docs.espressif.com/projects/esptool/en/latest/esp32/
// 参考2https://blog.csdn.net/espressif/article/details/105028809
execFile(ESP_TOOL_PATH,
['--chip', 'esp32', '--port', mainWindow.selectedPort ? mainWindow.selectedPort.portName : '', '--baud', '921600', '--before', 'default_reset', '--after', 'hard_reset', 'write_flash', '-z', '--flash_mode', 'dio', '--flash_freq', '80m', '--flash_size', 'detect',
'0xe000' , BOOT_APP0_BIN_PATH,
'0x1000' , BOOT_LOADER_BIN_PATH,
'0x10000', bin_file_path,
'0x8000' , PARTITIONS_BIN_PATH], (err, stdout) => {
if (err) {
event.sender.send('BURN_PROGRAM_FEEDBACK', { err } )
} else {
event.sender.send('BURN_PROGRAM_FEEDBACK', { stdout })
}
});
}
launchOnlineSoftware(_: IpcMainEvent, param: any) {
// TODO: 添加http网址正则表达式验证
const { url } = param
this.subWindow = new OnlineSoftwareWindow(url, this.subWindowOptions)
this.showSubWindow()
}
launchLocalSoftware(_: IpcMainEvent, param: any) {
const { subWindowName } = param
switch (subWindowName) {
case 'BDAndTimeWindow':
this.subWindow = new BDAndTimeWindow(this.subWindowOptions)
break;
case 'BDCommunicationAssistantWindow':
this.subWindow = new BDCommunicationAssistantWindow(this.subWindowOptions)
break;
case 'BDComprehensiveExperimentalPlatformWindow':
this.subWindow = new BDComprehensiveExperimentalPlatformWindow(this.subWindowOptions)
break;
case 'BDDataAnalysisPlatformWindow':
this.subWindow = new BDDataAnalysisPlatformWindow(this.subWindowOptions)
break;
case 'BDPositionTrackRetracingWindow':
this.subWindow = new BDPositionTrackRetracingWindow(this.subWindowOptions)
break;
case 'BDSatellite3DPostureDisplayWindow':
this.subWindow = new BDSatellite3DPostureDisplayWindow(this.subWindowOptions)
break;
case 'BDSatelliteAttitudeControlWindow':
this.subWindow = new BDSatelliteAttitudeControlWindow(this.subWindowOptions)
break;
case 'BDSatelliteParameterMonitoringPlatformWindow':
this.subWindow = new BDSatelliteParameterMonitoringPlatformWindow(this.subWindowOptions)
break;
case 'BDSatelliteTimeConfigurationWindow':
this.subWindow = new BDSatelliteTimeConfigurationWindow(this.subWindowOptions)
break;
case 'VoltageMonitoringWindow':
this.subWindow = new VoltageMonitoringWindow(this.subWindowOptions)
break;
case 'WirelessCommunicationModuleConfigurationWindow':
this.subWindow = new WirelessCommunicationModuleConfigurationWindow(this.subWindowOptions)
break;
case 'BDMeteorologicalDataDisplayPlatformWindow':
this.subWindow = new BDMeteorologicalDataDisplayPlatformWindow(this.subWindowOptions)
break;
case 'BDMeteorologicalDataProtocolWindow':
this.subWindow = new BDMeteorologicalDataProtocolWindow(this.subWindowOptions)
break;
case 'ElectronicScreenDesignWindow':
this.subWindow = new ElectronicScreenDesignWindow(this.subWindowOptions)
break;
case 'GestureRecognitionWindow':
this.subWindow = new GestureRecognitionWindow(this.subWindowOptions)
break;
case 'ClockConfigWindow':
this.subWindow = new ClockConfigWindow(this.subWindowOptions)
break;
case 'FontDesignWindow':
this.subWindow = new FontDesignWindow(this.subWindowOptions)
break;
case 'NixieTubeConfigurationWindow':
this.subWindow = new NixieTubeConfigurationWindow(this.subWindowOptions)
break;
case 'DistanceCalculationToolWindow':
this.subWindow = new DistanceCalculationToolWindow(this.subWindowOptions)
break;
case 'GeneratingConstellationChartWindow':
this.subWindow = new GeneratingConstellationChartWindow(this.subWindowOptions)
break;
default:
break;
}
this.showSubWindow()
}
showSubWindow(): void {
if (!this.subWindow) return
this.subWindow.maximize()
this.subWindow.once('ready-to-show', () => {
this.subWindow?.show()
})
}
}

View File

@ -0,0 +1,7 @@
import { LocalSoftwareWindow } from '../LocalSoftwareWindow'
export class NixieTubeConfigurationWindow extends LocalSoftwareWindow {
constructor (options = {}) {
super('nixie-tube-configuration.html', options )
}
}

View File

@ -0,0 +1,7 @@
import { LocalSoftwareWindow } from '../LocalSoftwareWindow'
export class VoltageMonitoringWindow extends LocalSoftwareWindow {
constructor (options = {}) {
super('voltage-monitoring.html', options)
}
}

View File

@ -0,0 +1,7 @@
import { LocalSoftwareWindow } from '../LocalSoftwareWindow'
export class WirelessCommunicationModuleConfigurationWindow extends LocalSoftwareWindow {
constructor (options = {}) {
super('wireless-communication-module-configuration.html', options)
}
}