diff --git a/.DS_Store b/.DS_Store deleted file mode 100644 index 0384fae..0000000 Binary files a/.DS_Store and /dev/null differ diff --git a/.gitignore b/.gitignore index 6704566..6c4f60d 100644 --- a/.gitignore +++ b/.gitignore @@ -102,3 +102,6 @@ dist # TernJS port file .tern-port + +# Mac .DS Store +.DS_Store diff --git a/electron-react-boilerplate/.DS_Store b/electron-react-boilerplate/.DS_Store deleted file mode 100644 index cd14ff8..0000000 Binary files a/electron-react-boilerplate/.DS_Store and /dev/null differ diff --git a/electron-react-boilerplate/.erb/.DS_Store b/electron-react-boilerplate/.erb/.DS_Store deleted file mode 100644 index 5b81d16..0000000 Binary files a/electron-react-boilerplate/.erb/.DS_Store and /dev/null differ diff --git a/electron-react-boilerplate/assets/.DS_Store b/electron-react-boilerplate/assets/.DS_Store deleted file mode 100644 index c069b04..0000000 Binary files a/electron-react-boilerplate/assets/.DS_Store and /dev/null differ diff --git a/electron-react-boilerplate/package.json b/electron-react-boilerplate/package.json index ec074a3..7522698 100644 --- a/electron-react-boilerplate/package.json +++ b/electron-react-boilerplate/package.json @@ -1,6 +1,6 @@ { "name": "electron-react-boilerplate", - "productName": "ElectronReact", + "productName": "StyleGAN Electron", "description": "Electron application boilerplate based on React, React Router, Webpack, React Fast Refresh for rapid application development", "scripts": { "build": "concurrently \"yarn build:main\" \"yarn build:renderer\"", @@ -30,7 +30,7 @@ ] }, "build": { - "productName": "ElectronReact", + "productName": "StyleGAN Electron", "appId": "org.erb.ElectronReact", "files": [ "dist/", @@ -253,6 +253,7 @@ "electron-debug": "^3.1.0", "electron-is-dev": "^1.2.0", "electron-log": "^4.2.4", + "electron-store": "^8.0.2", "electron-updater": "^4.3.4", "express": "^4.17.1", "history": "^5.0.0", diff --git a/electron-react-boilerplate/release/.DS_Store b/electron-react-boilerplate/release/.DS_Store deleted file mode 100644 index b745d79..0000000 Binary files a/electron-react-boilerplate/release/.DS_Store and /dev/null differ diff --git a/electron-react-boilerplate/src/.DS_Store b/electron-react-boilerplate/src/.DS_Store deleted file mode 100644 index b301363..0000000 Binary files a/electron-react-boilerplate/src/.DS_Store and /dev/null differ diff --git a/electron-react-boilerplate/src/App.global.css b/electron-react-boilerplate/src/App.global.css index f09f7e9..1cfa9dc 100644 --- a/electron-react-boilerplate/src/App.global.css +++ b/electron-react-boilerplate/src/App.global.css @@ -2,7 +2,7 @@ * @NOTE: Prepend a `~` to css file paths that are in your node_modules * See https://github.com/webpack-contrib/sass-loader#imports */ -body { + body { position: relative; color: white; height: 100vh; @@ -50,9 +50,38 @@ a:hover { cursor: pointer; } -.Hello { +.Title { display: flex; justify-content: center; align-items: center; margin: 20px 0; } + +.Image { + display: flex; + justify-content: center; + align-items: center; + margin: 20px 0; +} + +.Parameter { + display: flex; + justify-content: center; + align-items: center; + margin: 20px 0; +} + + +.Button { + display: flex; + justify-content: center; + align-items: center; + margin: 20px 0; +} + +.PythonInterface { + display: flex; + justify-content: center; + align-items: center; + margin: 20px 0; +} \ No newline at end of file diff --git a/electron-react-boilerplate/src/App.tsx b/electron-react-boilerplate/src/App.tsx index 85738b3..a9f1929 100644 --- a/electron-react-boilerplate/src/App.tsx +++ b/electron-react-boilerplate/src/App.tsx @@ -1,10 +1,11 @@ -import React,{Fragment, useState} from 'react'; +import React, { Fragment, useState } from 'react'; import Slider from '@material-ui/core/Slider'; +import TextField from '@material-ui/core/TextField'; import { withStyles } from '@material-ui/core/styles'; import { BrowserRouter as Router, Switch, Route } from 'react-router-dom'; import './App.global.css'; //Import Inter-Process Communication -const ipcRenderer = window.require("electron").ipcRenderer; +const ipcRenderer = window.require("electron").ipcRenderer; //Create a slider style const PrettoSlider = withStyles({ @@ -41,115 +42,136 @@ const MainFrame = () => { // Number of slider per row const chunkSize = 5; + // Application State + const [isSetupReady, setIsSetupReady] = useState(false); + // Python Path + const [pythonPath, setPythonPath] = useState(''); // Variable to store ImageURI - const [imageData, setImageData] = useState() + const [imageData, setImageData] = useState(); // Variable to Loop Create Slider - const [chunklists,setChunkLists] = useState([[],[]]) + const [chunklists, setChunkLists] = useState([[], []]); // List of all avaiable tag - const [lists, setlists] = useState([]) + const [lists, setlists] = useState([]); // Variable to store TagValue - const [tagValue, setTagValue] = useState<{}>({"test":1.0}) + const [tagValue, setTagValue] = useState<{}>({ "test": 1.0 }); // Handle on Slider Value Changes - function handleInputChange(event,value,id) - { + function handleInputChange(event, value, id) { interface CustomDict { [index: string]: number; } let updatedValue: CustomDict; - let updatedKey = id.item - updatedValue = {} - updatedValue[updatedKey] = value - setTagValue({...tagValue, ...updatedValue}); + let updatedKey = id.item; + updatedValue = {}; + updatedValue[updatedKey] = value; + setTagValue({ ...tagValue, ...updatedValue }); } // handle on Create New Image - function handleOnCreate(){ - console.log("generate new images") - ipcRenderer.send('creation_event') + function handleOnCreate() { + console.log("generate new images...."); + ipcRenderer.send('creation_event'); } // handle on Modify Current Image - function handleOnModify(){ - console.log("modify images") - ipcRenderer.send('modification_event',tagValue) + function handleOnModify() { + console.log("modify images...."); + ipcRenderer.send('modification_event', tagValue); + } + + // setup Python Interface + function setupPythonPath() { + console.log("setup python path...."); + ipcRenderer.send('pythonpath_init', pythonPath); } // handle Create Slider UI - function handleSetChunk(){ - const groups = lists.map((e, i) => { - return i % chunkSize === 0 ? lists.slice(i, i + chunkSize) : ["null"]; - }).filter(function (el) {return el[0] !== "null";}); - setChunkLists(groups) + function handleSetChunk() { + const groups = lists.map((e, i) => { + return i % chunkSize === 0 ? lists.slice(i, i + chunkSize) : ["null"]; + }).filter(function (el) { return el[0] !== "null"; }); + setChunkLists(groups); } - function handleCreateTagValue(){ - var tag_value_obj = lists.reduce((o, key) => Object.assign(o, {[key]: 0.0}), {}); - setTagValue(tag_value_obj) + function handleCreateTagValue() { + var tag_value_obj = lists.reduce((o, key) => Object.assign(o, { [key]: 0.0 }), {}); + setTagValue(tag_value_obj); } // General state changes listener React.useEffect(() => { // Event Listener for changing image in Real-Time - ipcRenderer.on('inference image', (event, value) => { + ipcRenderer.on('Inference Image', (event, value) => { console.log(`Image name:${value.image_name}`); setImageData(value.image_data); - }) + }); // Event Listener for initialization ipcRenderer.on('Init Interface', (event, value) => { setlists(value); - }) + }); + ipcRenderer.on('Get Python Path', (event, value) => { + setPythonPath(value); + }); + ipcRenderer.on('Init Ready', (event, value) => { + setIsSetupReady(value); + }); }, []) // This is be executed when 'list' state changes (for initialization) - React.useEffect(() => { - handleSetChunk(); + React.useEffect(() => { + handleSetChunk(); handleCreateTagValue(); - console.log("state changes") }, [lists]) return (
-
-

electron-stylegan-interface

+
+

Electron StyleGAN2

-
- +
+
-
- - +
+
+ { chunklists.map((chunk) => ( { chunk.map((item) => ( - - - - + + + + )) } )) } - -
- handleInputChange(event,value,{item})}/> - - {item} - + handleInputChange(event, value, { item })} /> + + {item} +
+ + +
+ +
+ { setPythonPath(event.target.value) }} /> +
-
- - +
+ +
diff --git a/electron-react-boilerplate/src/main.dev.ts b/electron-react-boilerplate/src/main.dev.ts index 9fc3947..99851ec 100644 --- a/electron-react-boilerplate/src/main.dev.ts +++ b/electron-react-boilerplate/src/main.dev.ts @@ -13,25 +13,24 @@ import 'regenerator-runtime/runtime'; import path from 'path'; import { app, BrowserWindow, shell, ipcMain } from 'electron'; import { autoUpdater } from 'electron-updater'; -import {PythonShell} from 'python-shell'; +import { PythonShell } from 'python-shell'; import log from 'electron-log'; import MenuBuilder from './menu'; -// Import Socketio Related Libraries +// Import Related Libraries const express = require('express'); const _app = express(); const server = require('http').Server(_app); const io = require('socket.io')(server); +const Store = require('electron-store'); +const store = new Store(); // Import Development Libraries const isDev = require('electron-is-dev'); // On Socketio Client Connected io.on('connection', (socket) => { - - // Initialize image when app opened io.emit('create_new_image'); - console.log('a user connected'); // Event on user disconnect socket.on('disconnect', () => { @@ -40,10 +39,9 @@ io.on('connection', (socket) => { // Pytorch Interface Event Listener socket.on('inference image', (msg) => { - console.log('image_name: ' + msg.image_name); - mainWindow.webContents.send('inference image', msg); + mainWindow.webContents.send('Inference Image', msg); }); - + // Event for initialize User Interface socket.on('Init Interface', (msg) => { mainWindow.webContents.send('Init Interface', msg); @@ -109,8 +107,10 @@ const createWindow = async () => { mainWindow = new BrowserWindow({ show: false, - width: 1024, - height: 728, + width: 1096, + height: 956, + minWidth: 1096, + minHeight: 956, icon: getAssetPath('icon.png'), webPreferences: { nodeIntegration: true, @@ -122,33 +122,6 @@ const createWindow = async () => { // @TODO: Use 'ready-to-show' event // https://github.com/electron/electron/blob/master/docs/api/browser-window.md#using-ready-to-show-event mainWindow.webContents.on('did-finish-load', () => { - console.log("finished loading"); - - if (isDev) { - // Running in Development Mode - const app_path = app.getAppPath().split("/"); - const base_app_path = app_path.slice(0, app_path.length-1).join("/"); - const StyleGANPATH = path.join(base_app_path, 'stylegan2_pytorch'); - process.chdir(StyleGANPATH); - - // Running Python Backended Script !!!!! - var pyshell = PythonShell.run('socket_inference.py',{scriptPath: StyleGANPATH ,pythonPath: '/Users/webkasidit/opt/anaconda3/envs/StyleGAN/bin/python' }, function (err, results) { - if (err) throw err; - console.log('Script Passes'); - }); - console.log('Running in development'); - } else { - // Running in Production Mode - const StyleGANPATH = path.join(process.resourcesPath, 'stylegan2_pytorch'); - process.chdir(StyleGANPATH); - // Running Python Backended Script !!!!! - var pyshell = PythonShell.run('socket_inference.py',{scriptPath: StyleGANPATH ,pythonPath: '/Users/webkasidit/opt/anaconda3/envs/StyleGAN/bin/python' }, function (err, results) { - if (err) throw err; - console.log('Script Passes'); - }); - console.log('Running in production'); - } - if (!mainWindow) { throw new Error('"mainWindow" is not defined'); } @@ -158,6 +131,7 @@ const createWindow = async () => { mainWindow.show(); mainWindow.focus(); } + mainWindow.webContents.send('Get Python Path', store.get('python_path')); }); mainWindow.on('closed', () => { @@ -184,25 +158,55 @@ const createWindow = async () => { // Listening Creation Event from Render process ipcMain.on("creation_event", () => { - console.log('Generate New Samples'); // Send Command through Socketio io.emit('create_new_image'); -}) +}); // Listening Modification Event from Render Process -ipcMain.on("modification_event", (event,args) => { +ipcMain.on("modification_event", (event, args) => { // Send Command through Socketio - io.emit('modify_current_image',args); -}) + io.emit('modify_current_image', args); +}); -app.on('window-all-closed', () => { - // Respect the OSX convention of having the application in memory even - // after all windows have been closed - if (process.platform !== 'darwin') { - app.quit(); +// Listening Python path initialization event from Render Process +ipcMain.on("pythonpath_init", (event, args) => { + // Set Python Path in persistant storage + store.set('python_path', args); + if (isDev) { + // Running in Development Mode + const app_path = app.getAppPath().split("/"); + const base_app_path = app_path.slice(0, app_path.length - 1).join("/"); + const StyleGANPATH = path.join(base_app_path, 'stylegan2_pytorch'); + process.chdir(StyleGANPATH); + // Running Python Backended Script + PythonShell.run('socket_inference.py', { scriptPath: StyleGANPATH, pythonPath: store.get('python_path') }, function (err, results) { + if (err) throw err; + }); + mainWindow.webContents.send('Init Ready', true); + console.log('Running in development'); + } else { + // Running in Production Mode + const StyleGANPATH = path.join(process.resourcesPath, 'stylegan2_pytorch'); + process.chdir(StyleGANPATH); + // Running Python Backended Script + PythonShell.run('socket_inference.py', { scriptPath: StyleGANPATH, pythonPath: store.get('python_path') }, function (err, results) { + if (err) throw err; + }); + mainWindow.webContents.send('Init Ready', true); + console.log('Running in production'); } }); +// Second Layer Exception Caughting +process.on('uncaughtException', function (error) { + mainWindow.webContents.send('Init Ready', false); +}); + +app.on('window-all-closed', () => { + app.quit(); + +}); + app.whenReady().then(createWindow).catch(console.log); app.on('activate', () => { diff --git a/electron-react-boilerplate/stylegan2_pytorch/.DS_Store b/electron-react-boilerplate/stylegan2_pytorch/.DS_Store deleted file mode 100644 index edd7993..0000000 Binary files a/electron-react-boilerplate/stylegan2_pytorch/.DS_Store and /dev/null differ diff --git a/electron-react-boilerplate/stylegan2_pytorch/pretrained_model/.DS_Store b/electron-react-boilerplate/stylegan2_pytorch/pretrained_model/.DS_Store deleted file mode 100644 index 6af817e..0000000 Binary files a/electron-react-boilerplate/stylegan2_pytorch/pretrained_model/.DS_Store and /dev/null differ diff --git a/electron-react-boilerplate/stylegan2_pytorch/pretrained_model/modded_dlatents/.DS_Store b/electron-react-boilerplate/stylegan2_pytorch/pretrained_model/modded_dlatents/.DS_Store deleted file mode 100644 index d6588b4..0000000 Binary files a/electron-react-boilerplate/stylegan2_pytorch/pretrained_model/modded_dlatents/.DS_Store and /dev/null differ diff --git a/electron-react-boilerplate/stylegan2_pytorch/stylegan2/.DS_Store b/electron-react-boilerplate/stylegan2_pytorch/stylegan2/.DS_Store deleted file mode 100644 index c022d91..0000000 Binary files a/electron-react-boilerplate/stylegan2_pytorch/stylegan2/.DS_Store and /dev/null differ