experimenting with preact render + electron backend...

Signed-off-by: Alex A. Naanou <alex.nanou@gmail.com>
This commit is contained in:
Alex A. Naanou 2017-07-26 21:10:28 +03:00
parent 458a67b4b4
commit 05c6e5c0c7
3 changed files with 284 additions and 0 deletions

69
ui (gen4)/e.js Normal file
View File

@ -0,0 +1,69 @@
#!/usr/bin/env node
/**********************************************************************
*
* ImageGrid.Viewer Electron entry point...
*
*
**********************************************************************/
var electron = require('electron')
var app = electron.app
var BrowserWindow = electron.BrowserWindow
var path = require('path')
var url = require('url')
/*********************************************************************/
var win
function createWindow () {
// Create the browser window.
win = new BrowserWindow({width: 800, height: 600})
// and load the index.html of the app.
win.loadURL(url.format({
pathname: path.join(__dirname, 'index.html'),
protocol: 'file:',
slashes: true
}))
// Open the DevTools.
win.webContents.openDevTools()
// Emitted when the window is closed.
win.on('closed', () => {
// Dereference the window object, usually you would store windows
// in an array if your app supports multi windows, this is the time
// when you should delete the corresponding element.
win = null
})
}
// This method will be called when Electron has finished
// initialization and is ready to create browser windows.
// Some APIs can only be used after this event occurs.
app.on('ready', createWindow)
// Quit when all windows are closed.
app.on('window-all-closed', () => {
// On macOS it is common for applications and their menu bar
// to stay active until the user quits explicitly with Cmd + Q
process.platform !== 'darwin'
&& app.quit()
})
app.on('activate', () => {
// On macOS it's common to re-create a window in the app when the
// dock icon is clicked and there are no other windows open.
win === null
&& createWindow()
})
/**********************************************************************
* vim:set ts=4 sw=4 : */

View File

@ -0,0 +1,193 @@
<!DOCTYPE html>
<html>
<style>
.ribbon {
position: relative;
display: block;
float: left;
clear: left;
white-space: nowrap;
overflow: visible;
margin: 5px 0px;
width: auto;
}
.base.ribbon {
border-bottom: solid 5px red;
}
.image {
position: relative;
display: inline-block;
width: 100px;
height: 100px;
outline: solid 1px blue;
background: silver;
}
.current.image {
background: gray;
}
.mark {
position: absolute;
}
</style>
<script src="../ext-lib/jquery.js"></script>
<script src="../ext-lib/jquery-ui.js"></script>
<!-- preact.js -->
<script src="../node_modules/preact/dist/preact.min.js"></script>
<script src="../lib/jli.js"></script>
<script>
var h = preact.h
var stub_data = {
ribbon_order: ['ra', 'rb', 'rc'],
ribbons: {
ra: [].slice.call('abcde'),
rb: [].slice.call('fghijklm'),
rc: [].slice.call('opqrstuvwxyz'),
},
order: [].slice.call('abcdefghijklmopqrstuvwxyz'),
tags: {
a: [].slice.call('ahdtu'),
b: [].slice.call('adxz'),
},
current: 'a',
base: 'rb',
}
// XXX needs vertical align...
class IGRibbonSet extends preact.Component {
render(props, state){
var data = props.data
var ribbons = data.ribbon_order.map(function(gid){
return h(IGRibbon, {
gid: gid,
current: data.current,
base: data.base,
data: data
}) })
var s = props.scale || 1
return h('div',
{
className: 'ribbon-set',
style: {
transform: 'scale('+ s +', '+ s +')',
},
}, [
h('div', {className: 'current-marker'}),
h('div', {className: 'ribbon-locator'}, ribbons),
])
}
}
// render:
// - ribbon
// - images
// - image marks
//
// XXX needs horizontal align...
class IGRibbon extends preact.Component {
render(props, state){
var data = props.data
var ribbon = props.gid
var images = data.ribbons[ribbon].map(function(gid){
return h(IGImage, {
gid: gid,
data: data
})})
var base = data.base == ribbon ? ['base'] : []
return h('div',
{
classList: ['ribbon'].concat(base).join(' '),
gid: props.gid,
style: {
// XXX offset...
},
}, images)
}
}
// render:
// - image
class IGImage extends preact.Component {
render(props, state){
var data = props.data
return h('div',
{
classList: ['image']
.concat(data.current == props.gid ? ['current'] : [])
.join(' '),
gid: props.gid || '',
style: {
// XXX background-image...
},
}, [
props.gid
])
}
}
// render:
// - image mark
class IGImageMark extends preact.Component {
render(props, state){
return h('div',
{
classList: ['mark'],
gid: props.gid,
})
}
}
var ribbon_set_dom
function render(data, images, scale){
//preact.render(ribbon_set, document.body)
ribbon_set_dom = preact.render(
h(IGRibbonSet, {
data: data || stub_data,
images: images || {},
scale: scale || 1,
}),
document.getElementById('viewer'),
ribbon_set_dom)
}
$(function(){ render() })
</script>
<body>
<div id="viewer"/>
</body>
</html>
<!-- vim:set ts=4 sw=4 : -->

View File

@ -41,8 +41,30 @@ var ribbons = require('imagegrid/ribbons')
// - ribbon-set // - ribbon-set
// - ribbon-locator // - ribbon-locator
// - current-indicator (???) // - current-indicator (???)
//
// * this is static and only created once...
class IGRibbonSet extends preact.Component { class IGRibbonSet extends preact.Component {
render(props, state){ render(props, state){
// XXX need:
// - scale
// - ribbons
var ribbons = data.ribbon_order
.map(function(gid){ return h(IGRibbon, {
ribbon: gid,
// XXX
}) })
return h('div.ribbon-set',
{
style: {
transform: 'scale('+ s +', '+ s +')',
},
}, [
h('div.current-marker'),
h('div.ribbon-locator', null, ribbons),
])
} }
} }