Skip to content

Commit

Permalink
1.0.0 version
Browse files Browse the repository at this point in the history
  • Loading branch information
Egahp committed Apr 11, 2022
1 parent 7286e3f commit 03d0963
Show file tree
Hide file tree
Showing 49 changed files with 8,801 additions and 242 deletions.
28 changes: 26 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,32 @@
# Cherry USB Configurator
> 用于生成 USB 描述符的图形化配置工具.

Cherry USB Configurator 是一个简单的易于上手的用于生成 USB 描述符的图形化配置工具.

## 功能简介

Cherry USB Configurator 基于Electron11 + Vue3.2 + Vite2 + TypeScript开发。
在Cherry USB Configurator里USB描述符被分割成了两种文件
一种是chrybase工程文件, 包含设备描述符、配置描述符和多组功能描述符的配置
另一种是chry文件, 包含了一组功能的接口关联描述符, 接口描述符, 类特定描述符, 端点描述符的配置
参考 test/demo文件内容

Cherry USB Configurator 预计实现一下功能:
- [x] 支持 USB2.0 全速和高速设备描述符配置
- [x] 支持设备描述符生成
- [x] 支持配置描述符生成
- [x] 支持字符串描述符生成
- [x] 支持接口描述符生成
- [x] 支持接口关联描述符生成
- [x] 支持端点描述符生成
- [x] 支持 HID 类描述符生成
- [x] 支持 MSC 类描述符生成
- [x] 支持 CDC ACM 类描述符生成
- [ ] 支持 UAC 1.0 描述符生成
- [ ] 支持 UAC 2.0 描述符生成
- [ ] 支持 UVC 描述符生成
- [ ] 支持多组配置描述符生成


# Electron11 + Vue3.2 + Vite2 + TypeScript

<br><br>

Expand Down
189 changes: 189 additions & 0 deletions packages/main/PvlDialog.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,189 @@
/****
******************************************************************************
* @file PvlDialog.ts
* @brief Dialog
* @author Egahp
* [email protected]
* @version 1.0
* @date 2022.03.29
******************************************************************************
* @attention
*
* <h2><center>&copy; Copyright 2021 Egahp.
* All rights reserved.</center></h2>
*
* @htmlonly
* <span style='font-weight: bold'>History</span>
* @endhtmlonly
* 版本|作者|时间|描述
* ----|----|----|----
* 1.0|Egahp|2022.03.29|创建文件
*****************************************************************************
*/


/* import --------------------------------------------------------------------*/
import { dialog, BrowserWindow, FileFilter, MessageBoxOptions, MessageBoxReturnValue, OpenDialogOptions, OpenDialogReturnValue, SaveDialogOptions, SaveDialogReturnValue } from 'electron';

/* interface -----------------------------------------------------------------*/
export interface IPvlDialogOptions
{
defaultPath?: string;
title?: string;
buttonLabel?: string;
filters?: FileFilter[];
multiSelections?: boolean;
}

interface IinternalPvlDialogOptions extends IPvlDialogOptions
{
pickFolders?: boolean;
pickFiles?: boolean;
}

export interface IPvlDialog {
pickFile(options:IPvlDialogOptions, window?:BrowserWindow): Promise<string[] | undefined>;
pickFolder(options:IPvlDialogOptions, window?:BrowserWindow): Promise<string[] | undefined>;
pickFileFolder(options:IPvlDialogOptions, window?:BrowserWindow): Promise<string[] | undefined>;
saveAs(options:IPvlDialogOptions, window?:BrowserWindow): Promise<string | undefined>;

showMessageBox(options:MessageBoxOptions, window?:BrowserWindow): Promise<MessageBoxReturnValue>;
showSaveDialog(options:SaveDialogOptions, window?:BrowserWindow): Promise<SaveDialogReturnValue>;
showOpenDialog(options:OpenDialogOptions, window?:BrowserWindow): Promise<OpenDialogReturnValue>;
}

/* data ----------------------------------------------------------------------*/

/* methods -------------------------------------------------------------------*/

/* class ---------------------------------------------------------------------*/
export class PvlDialog implements IPvlDialog {

pickFile(options:IPvlDialogOptions, window?:BrowserWindow): Promise<string[] | undefined>{
return this.doPick({ ...options, pickFiles:true, title: (options.title || "Open File")}, window);
}

pickFolder(options:IPvlDialogOptions, window?:BrowserWindow): Promise<string[] | undefined>{
return this.doPick({ ...options, pickFolders:true, title: (options.title || "Open Folder")}, window);
}

pickFileFolder(options:IPvlDialogOptions, window?:BrowserWindow): Promise<string[] | undefined>{
return this.doPick({ ...options, pickFiles:true, pickFolders:true, title: (options.title || "Open")}, window);
}

saveAs(options: IPvlDialogOptions, window?: BrowserWindow): Promise<string | undefined> {
return this.doSaveAs({ ...options, title: (options.title || "Save As")}, window);
}

private withNullAsUndefined<T>(x: T | null): T | undefined {
return x === null ? undefined : x;
}

private withUndefinedAsNull<T>(x: T | undefined): T | null {
return typeof x === 'undefined' ? null : x;
}

private async doPick(options:IinternalPvlDialogOptions, window?: BrowserWindow): Promise<string[] | undefined> {
const dialogOptions: OpenDialogOptions = {
title: options.title,
buttonLabel: options.buttonLabel,
filters: options.filters
};

dialogOptions.defaultPath = options.defaultPath;

if (typeof options.pickFiles === 'boolean' || typeof options.pickFolders === 'boolean') {
dialogOptions.properties = undefined; // let it override based on the booleans

if (options.pickFiles && options.pickFolders) {
if (typeof options.multiSelections === 'boolean'){
if (options.multiSelections){
dialogOptions.properties = ['multiSelections', 'openDirectory', 'openFile', 'createDirectory'];
}
else{
dialogOptions.properties = ['openDirectory', 'openFile', 'createDirectory'];
}
}
else{
dialogOptions.properties = ['multiSelections', 'openDirectory', 'openFile', 'createDirectory'];
}
}
}

if (!dialogOptions.properties) {
if (typeof options.multiSelections === 'boolean'){
if (options.multiSelections){
dialogOptions.properties = ['multiSelections', options.pickFolders ? 'openDirectory' : 'openFile', 'createDirectory'];
}
else{
dialogOptions.properties = [options.pickFolders ? 'openDirectory' : 'openFile', 'createDirectory'];
}
}
else{
dialogOptions.properties = ['multiSelections', options.pickFolders ? 'openDirectory' : 'openFile', 'createDirectory'];
}

}

// Show Dialog
const windowToUse = window || BrowserWindow.getFocusedWindow();

const result = await this.showOpenDialog(dialogOptions, this.withNullAsUndefined(windowToUse));
if (result && result.filePaths && result.filePaths.length > 0) {
return result.filePaths;
}

return;
}

private async doSaveAs(options: IPvlDialogOptions, window?: BrowserWindow): Promise<string | undefined> {
const dialogOptions:SaveDialogOptions = {
title: options.title,
buttonLabel: options.buttonLabel,
filters: options.filters
};

dialogOptions.defaultPath = options.defaultPath;

dialogOptions.properties = ['showHiddenFiles','showOverwriteConfirmation','createDirectory'];

const windowToUse = window || BrowserWindow.getFocusedWindow();

const result = await this.showSaveDialog(dialogOptions, this.withNullAsUndefined(windowToUse));

if (result && result.filePath){
return result.filePath;
}

return undefined;
}

showMessageBox(options:MessageBoxOptions, window?:BrowserWindow): Promise<MessageBoxReturnValue>{
const windowToUse = window || this.withNullAsUndefined(BrowserWindow.getFocusedWindow());

if (typeof windowToUse !== "undefined"){
return dialog.showMessageBox(windowToUse, options);
} else {
return dialog.showMessageBox(options);
}
}

showSaveDialog(options:SaveDialogOptions, window?:BrowserWindow): Promise<SaveDialogReturnValue>{
if (window){
return dialog.showSaveDialog(window, options);
} else {
return dialog.showSaveDialog(options);
}
}

showOpenDialog(options:OpenDialogOptions, window?:BrowserWindow): Promise<OpenDialogReturnValue>{
if (window){
return dialog.showOpenDialog(window, options);
} else {
return dialog.showOpenDialog(options);
}
}
}
/* export --------------------------------------------------------------------*/

/************************ (C) COPYRIGHT 2021 Egahp *****END OF FILE************/
Loading

0 comments on commit 03d0963

Please sign in to comment.