Skip to content

Commit

Permalink
Add Electron framework.
Browse files Browse the repository at this point in the history
As of this commit you can now do

    npm start

to launch the electron based app, choose File -> Open to
open templates/cube/index.html, edit the slides (but not
create or add slides) and the save it with File -> Save as.

Note: It won't work with any other impress presentation, as
tinymce.js and impressionist.[js|css] are still in the index.html
file hard coded. Also the saved file isn't really clean, since it
will save the tinymce toolbar, dialogs and the impressionist camera
controls. All of this will change in future commits of course.

So the cool part of this commit is simply that you can launch an
Electron app now.
  • Loading branch information
Henrik Ingo committed Oct 22, 2016
1 parent 3e41542 commit 7abb13b
Show file tree
Hide file tree
Showing 9 changed files with 203 additions and 8 deletions.
1 change: 1 addition & 0 deletions build.js
Expand Up @@ -6,6 +6,7 @@ buildify()
.concat(['src/plugins/axis/axis.js',
'src/plugins/camera/camera.js',
'src/plugins/cameracontrols/cameracontrols.js',
'src/plugins/electron/electron.js',
'src/plugins/tinymce/tinymce.js',
'src/plugins/toolbar/toolbar.js'])
.save('js/impressionist.js')
Expand Down
Binary file added favicon.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
26 changes: 26 additions & 0 deletions js/impressionist.js
Expand Up @@ -739,6 +739,32 @@
})(document, window);


/**
* Electron IPC
*
* This is the renderer side of some Electron IPC calls.
*
* Copyright 2016 Henrik Ingo (@henrikingo)
* Released under the MIT license.
*/
(function ( document, window ) {
'use strict';

// Return the entire document when requested
// TODO: We need to actually remove the impressionist and tinymce controls first and return just the impress.js bits
if( require ){
var ipc = require('electron').ipcRenderer;
ipc.on('impressionist-get-documentElement', function (event, filename) {
ipc.send('impressionist-return-documentElement', {
filename: filename,
// TODO: I have no idea why the closing </html> is missing from innerHTML
documentElement: document.documentElement.innerHTML + "\n</html>"
});
});
}

})(document, window);

/**
* Tinymce integration
*
Expand Down
38 changes: 38 additions & 0 deletions main.js
@@ -0,0 +1,38 @@
const electron = require('electron')
const app = electron.app
const BrowserWindow = electron.BrowserWindow
const menu = require('./src/main/menu')

// Keep a global reference of the window object, if you don't, the window will
// be closed automatically when the JavaScript object is garbage collected.
let mainWindow

function createWindow () {
// Create the browser window.
mainWindow = new BrowserWindow({useContentSize: true,
icon: './favicon.png'})
mainWindow.maximize()
// debug
mainWindow.webContents.openDevTools()

mainWindow.on('closed', function () {
mainWindow = null
})
menu.createMenu(mainWindow)
}

app.on('ready', createWindow)
app.on('window-all-closed', function () {
// On OS X it is common for applications and their menu bar
// to stay active until the user quits explicitly with Cmd + Q
if (process.platform !== 'darwin') {
app.quit()
}
})
app.on('activate', function () {
// On OS X it's common to re-create a window in the app when the
// dock icon is clicked and there are no other windows open.
if (mainWindow === null) {
createWindow()
}
})
18 changes: 10 additions & 8 deletions package.json
Expand Up @@ -5,12 +5,12 @@
"version": "0.1.0",
"description": "A visual editor for creating 3D impress.js presentations",
"homepage": "http://github.com/henrikingo/impressionist",
"main": "js/impressionist.js",
"repository" :
{ "type" : "git",
"url" : "https://github.com/henrikingo/impressionist.git",
"github": "https://github.com/henrikingo/impressionist"
},
"main": "main.js",
"repository": {
"type": "git",
"url": "https://github.com/henrikingo/impressionist.git",
"github": "https://github.com/henrikingo/impressionist"
},
"keywords": [
"presentation",
"slides",
Expand All @@ -26,12 +26,14 @@
"url": "https://github.com/henrikingo/impressionist/issues"
},
"scripts": {
"build": "node build.js"
"build": "node build.js",
"start": "electron ."
},
"dependencies": {
"tinymce": "*"
},
"devDependencies": {
"buildify": "*"
"buildify": "*",
"electron": "^1.4.1"
}
}
1 change: 1 addition & 0 deletions src/main/README.md
@@ -0,0 +1 @@
Files required from the Electron main.js process
63 changes: 63 additions & 0 deletions src/main/fileOpenSave.js
@@ -0,0 +1,63 @@
/* File open and save. (Dialogs and implementation) */
const electron = require('electron')
const app = electron.app



let mainWindowPointer = null
let currentFile = ""
const dialog = require('electron').dialog

var fileOpen = function(){
dialog.showOpenDialog({
title: 'Open Presentation',
filters: [
{ name: 'Impress Presentation (HTML)', extensions: ['html'] }
],
properties: ['openFile']
}, function (files) {
if (files) {
currentFile = files[0]
mainWindowPointer.loadURL('file://' + currentFile)
}
})
};

const ipc = require('electron').ipcMain
const fs = require('fs')
var fileSave = function() {
mainWindowPointer.webContents.send('impressionist-get-documentElement', currentFile)
}

var fileSaveAs = function() {
dialog.showSaveDialog({
title: 'Save Presentation',
filters: [
{ name: 'Impress Presentation (HTML)', extensions: ['html'] }
]
}, function (filename) {
if (filename) {
currentFile = filename
mainWindowPointer.webContents.send('impressionist-get-documentElement', currentFile)
}
})
}
ipc.on('impressionist-return-documentElement', function(event, data){
fs.writeFile(data.filename, data.documentElement, function (err) {
if(err){
console.log("An error ocurred creating the file "+ err.message)
}
console.log(`${data.filename} has been succesfully saved`);
})
})

module.exports = {
init: function(mainWindow){
mainWindowPointer = mainWindow
return {
open: fileOpen,
save: fileSave,
saveAs: fileSaveAs
}
}
}
39 changes: 39 additions & 0 deletions src/main/menu.js
@@ -0,0 +1,39 @@
const electron = require('electron')
const app = electron.app
const Menu = electron.Menu

/* Menu */
module.exports = {
createMenu: function(mainWindow){
let file = require('./fileOpenSave').init(mainWindow)

var menuLabel = "&File"
if (process.platform === 'darwin') {
menuLabel = electron.app.getName()
}

let template = [{
label: menuLabel,
submenu: [{
label: '&Open',
accelerator: 'CmdOrCtrl+O',
click: file.open
}, {
label: '&Save',
accelerator: 'CmdOrCtrl+S',
click: file.save
}, {
label: 'Save &As...',
accelerator: 'Shift+CmdOrCtrl+S',
click: file.saveAs
}, {
label: 'Quit',
accelerator: 'CmdOrCtrl+Q',
role: 'quit'
}]
}]

const menu = Menu.buildFromTemplate(template)
Menu.setApplicationMenu(menu)
}
}
25 changes: 25 additions & 0 deletions src/plugins/electron/electron.js
@@ -0,0 +1,25 @@
/**
* Electron IPC
*
* This is the renderer side of some Electron IPC calls.
*
* Copyright 2016 Henrik Ingo (@henrikingo)
* Released under the MIT license.
*/
(function ( document, window ) {
'use strict';

// Return the entire document when requested
// TODO: We need to actually remove the impressionist and tinymce controls first and return just the impress.js bits
if( require ){
var ipc = require('electron').ipcRenderer;
ipc.on('impressionist-get-documentElement', function (event, filename) {
ipc.send('impressionist-return-documentElement', {
filename: filename,
// TODO: I have no idea why the closing </html> is missing from innerHTML
documentElement: document.documentElement.innerHTML + "\n</html>"
});
});
}

})(document, window);

0 comments on commit 7abb13b

Please sign in to comment.