From 70b65d034f6792c7830776c5b86a38304a546d88 Mon Sep 17 00:00:00 2001 From: "Alex A. Naanou" Date: Wed, 4 Oct 2017 17:07:22 +0300 Subject: [PATCH] started work on Electron runtime... Signed-off-by: Alex A. Naanou --- ui (gen4)/e.js | 12 +- ui (gen4)/features/app.js | 260 ++++++++++++++++++++++++++++---------- ui (gen4)/package.json | 10 +- 3 files changed, 207 insertions(+), 75 deletions(-) diff --git a/ui (gen4)/e.js b/ui (gen4)/e.js index 5b6fec0b..3258f827 100644 --- a/ui (gen4)/e.js +++ b/ui (gen4)/e.js @@ -22,7 +22,17 @@ var win function createWindow() { // Create the browser window. - win = new BrowserWindow({width: 800, height: 600}) + win = new BrowserWindow({ + // XXX get from config... + width: 800, + height: 600, + + fullscreenable: true, + //backgroundColor: XXX, + + // XXX remove... + autoHideMenuBar: true, + }) // and load the index.html of the app. win.loadURL(url.format({ diff --git a/ui (gen4)/features/app.js b/ui (gen4)/features/app.js index 49e0b258..5ac6b4ca 100755 --- a/ui (gen4)/features/app.js +++ b/ui (gen4)/features/app.js @@ -22,6 +22,188 @@ var base = require('features/base') /*********************************************************************/ +var NWHostActions = actions.Actions({ + get title(){ + return nw.Window.get().title }, + set title(value){ + nw.Window.get().title = value }, + + minimize: ['Window/Minimize', + function(){ + nw.Window.get().minimize() }], + toggleFullScreen: ['Window/Full screen mode', + toggler.CSSClassToggler( + function(){ return document.body }, + '.full-screen-mode', + function(action){ + var that = this + var w = nw.Window.get() + + // change the state only if the target state is not the same + // as the current state... + if((w.isFullscreen ? 'on' : 'off') != action){ + this.ribbons.preventTransitions() + + // hide the viewer to hide any animation crimes... + this.dom[0].style.visibility = 'hidden' + + // XXX async... + // ...this complicates things as we need to do the next + // bit AFTER the resize is done... + w.toggleFullscreen() + + setTimeout(function(){ + that + .centerViewer() + .focusImage() + .ribbons + .restoreTransitions() + + that.dom[0].style.visibility = '' + }, 100) + } + + // NOTE: we delay this to account for window animation... + setTimeout(function(){ + that.storeWindowGeometry() + }, 500) + })], + + // XXX add ability to use devtools on background page (node context)... + showDevTools: ['Interface|Development/Show Dev Tools', + function(){ + nw.Window.get().showDevTools && + nw.Window.get().showDevTools() + }], + + // XXX should this be here??? + showInFolder: ['File|Image/Show in $folder', + function(image){ + image = this.images[this.data.getImage(image)] + + var base = image.base_path || this.location.path + var filename = image.path + var path = pathlib.normalize(base + '/' + filename) + + nw.Shell.showItemInFolder(path) + }], +}) + +var NWHost = +module.NWHost = core.ImageGridFeatures.Feature({ + title: '', + doc: '', + + tag: 'ui-nw-host', + exclusive: 'ui-host', + depends: [], + + actions: NWHostActions, + + isApplicable: function(){ return this.runtime.nw }, +}) + + + +//--------------------------------------------------------------------- + +var ElectronHostActions = actions.Actions({ + get title(){ + }, + set title(value){ + }, + + minimize: ['Window/Minimize', + function(){ + // XXX + }], + + showDevTools: ['Interface|Development/Show Dev Tools', + function(){ + // XXX + }], + + showInFolder: ['File|Image/Show in $folder', + function(image){ + // XXX + }], + + // XXX this is almost generic, but it is not usable unless within + // a user event handler... + // ...can we use this on electron??? + toggleFullScreen: ['Window/Full screen mode', + toggler.CSSClassToggler( + function(){ return document.body }, + '.full-screen-mode', + function(action){ + var that = this + + var state = (document.fullScreenElement + && document.fullScreenElement !== null) ? + 'on' + : 'off' + + // change the state only if the target state is not the same + // as the current state... + if(state != action){ + this.ribbons.preventTransitions() + + // hide the viewer to hide any animation crimes... + this.dom[0].style.visibility = 'hidden' + + // XXX async... + // ...this complicates things as we need to do the next + // bit AFTER the resize is done... + if(action == 'on'){ + var d = document.documentElement + ;(d.requestFullscreen + || d.webkitRequestFullscreen + || d.msRequestFullscreen + || d.mozRequestFullscreen)() + + } else { + ;(document.exitFullscreen + || document.webkitExitFullscreen + || document.msExitFullscreen + || document.mozExitFullscreen)() + } + + setTimeout(function(){ + that + .centerViewer() + .focusImage() + .ribbons + .restoreTransitions() + + that.dom[0].style.visibility = '' + }, 100) + } + + // NOTE: we delay this to account for window animation... + setTimeout(function(){ + that.storeWindowGeometry() + }, 500) + })], +}) + +var ElectronHost = +module.ElectronHost = core.ImageGridFeatures.Feature({ + title: '', + doc: '', + + tag: 'ui-electron-host', + exclusive: 'ui-host', + depends: [], + + actions: ElectronHostActions, + + isApplicable: function(){ return this.runtime.electron }, +}) + + + +//--------------------------------------------------------------------- + var AppControlActions = actions.Actions({ config: { //'window-title': 'ImageGrid.Viewer (${VERSION}): ${FILENAME}', @@ -33,6 +215,7 @@ var AppControlActions = actions.Actions({ // XXX revise these... close: ['File|Window/Close viewer', function(){ window.close() }], + // XXX make these generic -- use host API... storeWindowGeometry: ['- Window/Store window state', function(){ // store window parameters (size, state)... @@ -114,66 +297,6 @@ var AppControlActions = actions.Actions({ }, this.config['window-delay-initial-display'] || 0) }], - minimize: ['Window/Minimize', - function(){ - nw.Window.get().minimize() - }], - toggleFullScreen: ['Window/Full screen mode', - toggler.CSSClassToggler( - function(){ return document.body }, - '.full-screen-mode', - function(action){ - var that = this - var w = nw.Window.get() - - // change the state only if the target state is not the same - // as the current state... - if((w.isFullscreen ? 'on' : 'off') != action){ - this.ribbons.preventTransitions() - - // hide the viewer to hide any animation crimes... - this.dom[0].style.visibility = 'hidden' - - // XXX async... - // ...this complicates things as we need to do the next - // bit AFTER the resize is done... - w.toggleFullscreen() - - setTimeout(function(){ - that - .centerViewer() - .focusImage() - .ribbons - .restoreTransitions() - - that.dom[0].style.visibility = '' - }, 100) - } - - // NOTE: we delay this to account for window animation... - setTimeout(function(){ - that.storeWindowGeometry() - }, 500) - })], - - // XXX add ability to use devtools on background page (node context)... - showDevTools: ['Interface|Development/Show Dev Tools', - function(){ - nw.Window.get().showDevTools && - nw.Window.get().showDevTools() - }], - - // XXX should this be here??? - showInFolder: ['File|Image/Show in $folder', - function(image){ - image = this.images[this.data.getImage(image)] - - var base = image.base_path || this.location.path - var filename = image.path - var path = pathlib.normalize(base + '/' + filename) - - nw.Shell.showItemInFolder(path) - }], }) @@ -181,6 +304,7 @@ var AppControlActions = actions.Actions({ // XXX store/load window state... // - size // - state (fullscreen/normal) +// XXX for some magical reason this gets disabled on electron.... var AppControl = module.AppControl = core.ImageGridFeatures.Feature({ title: '', @@ -189,15 +313,13 @@ module.AppControl = core.ImageGridFeatures.Feature({ tag: 'ui-app-control', depends: [ 'ui', + 'ui-host', ], actions: AppControlActions, - // XXX test if in: - // - chrome app - // - nw - // - mobile - isApplicable: function(){ return this.runtime.nw }, + //isApplicable: function(){ return this.runtime.desktop }, + isApplicable: function(){ return this.runtime.desktop && !this.runtime.electron }, // XXX show main window... handlers: [ @@ -215,13 +337,14 @@ module.AppControl = core.ImageGridFeatures.Feature({ 'toggleFullScreen', ], function(){ this.storeWindowGeometry() }], + + // update window title... + // XXX make this generic... ['focusImage', function(){ - var win = nw.Window.get() - if(this.images){ var img = this.images[this.current] - win.title = (this.config['window-title'] + this.title = (this.config['window-title'] || 'ImageGrid.Viewer (${VERSION}): ${FILENAME}') // XXX get this from the viewer... .replace('${VERSION}', this.version || 'gen4') @@ -240,7 +363,6 @@ module.AppControl = core.ImageGridFeatures.Feature({ +'/'+ img.path.replace(/\.[\\\/]/, ''))) */ // XXX add ... - } }], ], diff --git a/ui (gen4)/package.json b/ui (gen4)/package.json index 3fd0906d..119e697a 100755 --- a/ui (gen4)/package.json +++ b/ui (gen4)/package.json @@ -18,18 +18,18 @@ "app-module-path": "^1.0.6", "commander": "^2.11.0", "exiftool": "^0.0.3", - "fs-extra": "^4.0.1", + "fs-extra": "^4.0.2", "fs-walk": "^0.0.1", "glob": "^4.0.6", "guarantee-events": "^1.0.0", "ig-actions": "^3.8.0", - "ig-features": "^3.2.7", + "ig-features": "^3.3.1", "ig-object": "^1.0.2", - "openseadragon": "^2.3.0", + "openseadragon": "^2.3.1", "pica": "^3.0.6", "preact": "^8.2.5", - "react": "^15.6.1", - "react-dom": "^15.6.1", + "react": "^15.6.2", + "react-dom": "^15.6.2", "requirejs": "^2.3.5", "requirejs-plugins": "^1.0.2", "sharp": "^0.17.3",