Remove Open/Save buttons from Model pane

This commit is contained in:
Tiago Koji Castro Shibata 2018-08-20 18:09:26 -07:00
Родитель 54ec8d2eb5
Коммит 64d73f60cf
8 изменённых файлов: 144 добавлений и 38 удалений

Просмотреть файл

@ -5,6 +5,7 @@ import { Provider } from 'react-redux'
import App from './App';
import store from './datastore/store';
import './index.css';
import { registerKeyboardShurtcuts } from './native/menu';
import registerServiceWorker from './registerServiceWorker';
ReactDOM.render(
@ -13,4 +14,5 @@ ReactDOM.render(
</Provider>,
document.getElementById('root') as HTMLElement
);
registerKeyboardShurtcuts();
registerServiceWorker();

Просмотреть файл

@ -0,0 +1,9 @@
import { fileFilterToAccept } from "./dialog";
it('converts Array<FileFilter> to HTML accept field', () => {
expect(fileFilterToAccept([
{ name: 'CoreML model', extensions: [ 'mlmodel' ] },
{ name: 'Keras model', extensions: [ 'keras', 'h5' ] },
{ name: 'ONNX model', extensions: [ 'onnx' ] },
])).toBe('.mlmodel,.keras,.h5,.onnx');
});

Просмотреть файл

@ -7,7 +7,7 @@ import * as path from 'path';
import { getElectron } from './util';
export function filterToAccept(filters: Electron.FileFilter[]) {
export function fileFilterToAccept(filters: Electron.FileFilter[]) {
/**
* Convert Electron FileFilter[] to HTML accept field.
*/
@ -46,7 +46,7 @@ export async function showOpenDialog(filters: Electron.FileFilter[]) {
return file as File;
});
}
return showWebOpenDialog(filterToAccept(filters));
return showWebOpenDialog(fileFilterToAccept(filters));
}
export function showWebSaveDialog(data: Uint8Array, filename: string) {

Просмотреть файл

@ -0,0 +1,117 @@
/**
* Provide native menus and shortcuts. In the web, installs shortcuts only.
*/
import { setFile } from "../datastore/actionCreators";
import { ModelProtoSingleton } from "../datastore/proto/modelProto";
import store from "../datastore/store";
import { save, showOpenDialog } from "./dialog";
import { isWeb } from "./util";
export function createMenu(electron: typeof Electron) {
const { Menu } = electron.remote;
const template = [
{
label: 'File',
submenu: [
{ label: 'Open', accelerator: 'Ctrl+O', click: onOpen },
{ label: 'Save', accelerator: 'Ctrl+S', click: onSave, enabled: false },
],
}, {
label: 'Edit',
submenu: [
{ role: 'undo' },
{ role: 'redo' },
{ type: 'separator' },
{ role: 'cut' },
{ role: 'copy' },
{ role: 'paste' },
{ role: 'pasteandmatchstyle' },
{ role: 'delete' },
{ role: 'selectall '},
],
}, {
label: 'View',
submenu: [
{ role: 'toggledevtools' },
{ type: 'separator' },
{ role: 'resetzoom' },
{ role: 'zoomin' },
{ role: 'zoomout' },
{ type: 'separator' },
{ role: 'togglefullscreen '},
],
}, {
role: 'help',
submenu: [
{ label: 'Project Page', click () { alert('TODO') } },
],
}
];
if (process.platform === 'darwin') {
template.unshift({
label: 'WinML Dashboard',
submenu: [
{ role: 'about' },
{ type: 'separator' },
{ role: 'services', submenu: [] },
{ type: 'separator' },
{ role: 'hide' },
{ role: 'hideothers' },
{ role: 'unhide' },
{ type: 'separator' },
{ role: 'quit '},
],
} as any);
}
const menu = Menu.buildFromTemplate(template as any);
store.subscribe(() => (menu.items[0] as any).submenu.items[1].enabled = !!store.getState().nodes);
Menu.setApplicationMenu(menu);
}
export function registerKeyboardShurtcuts() {
if (isWeb()) { // Electron's accelerators are used outside web builds
document.addEventListener('keydown', (event) => {
if (event.ctrlKey) {
switch (event.code) {
case 'KeyS':
onSave();
break;
case 'KeyO':
onOpen();
break;
default:
return;
}
event.preventDefault();
}
});
}
}
function onSave() {
if (ModelProtoSingleton.proto) {
save(ModelProtoSingleton.serialize(), 'model.onnx', [{ name: 'ONNX model', extensions: [ 'onnx', 'prototxt' ] }]);
}
}
async function onOpen() {
const files = await showOpenDialog([
{ name: 'ONNX Model', extensions: [ 'onnx', 'pb' ] },
{ name: 'Keras Model', extensions: [ 'h5', 'json', 'keras' ] },
{ name: 'CoreML Model', extensions: [ 'mlmodel' ] },
{ name: 'Caffe Model', extensions: [ 'caffemodel' ] },
{ name: 'Caffe2 Model', extensions: [ 'pb' ] },
{ name: 'MXNet Model', extensions: [ 'model', 'json' ] },
{ name: 'TensorFlow Graph', extensions: [ 'pb', 'meta' ] },
{ name: 'TensorFlow Saved Model', extensions: [ 'pb' ] },
{ name: 'TensorFlow Lite Model', extensions: [ 'tflite' ] }
]);
if (files) {
store.dispatch(setFile(files[0]));
}
}

Просмотреть файл

@ -3,7 +3,7 @@ import * as fs from 'fs';
import { createMenu } from './menu';
export function isWeb() {
return !fs.exists;
return !fs.exists || typeof it === 'function';
}
let electron: typeof Electron;

Просмотреть файл

@ -4,6 +4,7 @@ import { connect } from 'react-redux';
import Collapsible from '../../components/Collapsible';
import KeyValueEditor from '../../components/KeyValueEditor'
import Resizable from '../../components/Resizable';
import { setMetadataProps } from '../../datastore/actionCreators';
import IState, { IMetadataProps } from '../../datastore/state';
import MetadataSchema from '../../schema/Metadata';
@ -27,7 +28,7 @@ class RightPanel extends React.Component<IComponentProperties, {}> {
}
return (
<div>
<Resizable>
<Label>Model</Label>
<div className='Panel'>
<Collapsible label='Properties'>
@ -37,7 +38,7 @@ class RightPanel extends React.Component<IComponentProperties, {}> {
<KeyValueEditor actionCreator={setMetadataProps} getState={this.getMetadataPropsFromState} schema={MetadataSchema} />
</Collapsible>
</div>
</div>
</Resizable>
);
}

Просмотреть файл

@ -1,48 +1,19 @@
import { DefaultButton } from 'office-ui-fabric-react/lib/Button';
import * as React from 'react';
import Resizable from '../../components/Resizable';
import { ModelProtoSingleton } from '../../datastore/proto/modelProto';
import { showWebOpenDialog, showWebSaveDialog } from '../../native/dialog';
import LeftPanel from './LeftPanel';
import * as netron from './netron/Netron';
import { Netron } from './netron/Netron';
import RightPanel from './RightPanel';
import './View.css';
interface IComponentState {
file?: File,
}
export default class EditView extends React.Component<{}, IComponentState> {
constructor(props: {}) {
super(props);
this.state = {
file: undefined,
};
}
export default class EditView extends React.Component {
public render() {
return (
<div id='EditView'>
<LeftPanel />
<netron.Netron />
<Resizable>
<DefaultButton text='Open file' onClick={this.openFile}/>
<DefaultButton text='Save file' onClick={this.saveFile}/>
<RightPanel />
</Resizable>
<Netron />
<RightPanel />
</div>
);
}
private openFile = () =>
showWebOpenDialog('.onnx,.pb,.meta,.tflite,.keras,.h5,.json,.mlmodel,.caffemodel')
.then((files) => {
if (files) {
this.setState({ file: files[0] });
}
});
private saveFile = () => showWebSaveDialog(ModelProtoSingleton.serialize(), 'model.onnx');
}

Просмотреть файл

@ -0,0 +1,6 @@
{
"extends": "./tsconfig.json",
"compilerOptions": {
"module": "commonjs"
}
}