diff --git a/app/example/helloworld-html.js b/app/example/helloworld-html.js index 7e5408a..31252c7 100644 --- a/app/example/helloworld-html.js +++ b/app/example/helloworld-html.js @@ -19,7 +19,7 @@ AFRAME.registerComponent('helloworld-html', {
helloworld-html: ${me.data.foo} ${me.data.myvalue}
`, - css: `.helloworld-html { + css: (me) => `.helloworld-html { color: var(--xrsh-light-gray); /* see index.css */ }`, }, diff --git a/app/example/helloworld-htmlform.js b/app/example/helloworld-htmlform.js index ec242e0..f05830e 100644 --- a/app/example/helloworld-htmlform.js +++ b/app/example/helloworld-htmlform.js @@ -31,7 +31,7 @@ AFRAME.registerComponent('helloworld-htmlform', { `, - css: `.helloworld-htmlform > div { padding:11px; }` + css: (me) => `.helloworld-htmlform > div { padding:11px; }` }, diff --git a/app/example/helloworld-iframe.js b/app/example/helloworld-iframe.js index 1384048..4a115af 100644 --- a/app/example/helloworld-iframe.js +++ b/app/example/helloworld-iframe.js @@ -18,7 +18,7 @@ AFRAME.registerComponent('helloworld-iframe', { `, - css: ` + css: (me) => ` .XR #overlay .winbox.iframe{ visibility: visible; } /* don't hide in XR mode */ .winbox.iframe iframe { background:#FFF; } ` diff --git a/app/example/helloworld-window.js b/app/example/helloworld-window.js index c5d8765..8a103b8 100644 --- a/app/example/helloworld-window.js +++ b/app/example/helloworld-window.js @@ -18,7 +18,7 @@ AFRAME.registerComponent('helloworld-window', {
${me.data.foo} ${me.data.myvalue}
`, - css: `.helloworld-window div.pad { padding:11px; }` + css: (me) => `.helloworld-window div.pad { padding:11px; }` }, events:{ diff --git a/app/isoterminal.js b/app/isoterminal.js index dea102b..3db35e8 100644 --- a/app/isoterminal.js +++ b/app/isoterminal.js @@ -1,18 +1,18 @@ AFRAME.registerComponent('isoterminal', { - schema: { - cols: { type: 'number', default: 80 }, - rows: { type: 'number', default: 25 }, + schema: { + cols: { type: 'number', default: 120 }, + rows: { type: 'number', default: 50 }, transparent: { type:'boolean', default:false } // need good gpu }, - init: function(){ + init: function(){ this.el.object3D.visible = false }, requires:{ html: "https://unpkg.com/aframe-htmlmesh@2.1.0/build/aframe-html.js", // html to AFRAME winboxjs: "https://unpkg.com/winbox@0.2.82/dist/winbox.bundle.min.js", // deadsimple windows: https://nextapps-de.github.io/winbox - winboxcss: "https://unpkg.com/winbox@0.2.82/dist/css/winbox.min.css", // + winboxcss: "https://unpkg.com/winbox@0.2.82/dist/css/winbox.min.css", // xtermcss: "https://unpkg.com/xterm@3.12.0/dist/xterm.css", xtermjs: "https://unpkg.com/xterm@3.12.0/dist/xterm.js", axterm: "https://unpkg.com/aframe-xterm-component/aframe-xterm-component.js" @@ -23,23 +23,21 @@ AFRAME.registerComponent('isoterminal', { events: ['click','keydown'], html: (me) => `
`, - css: `.isoterminal{ - width:512px; - height:256px; + css: (me) => `.isoterminal{ overflow:hidden; }` }, createTerminal: function(){ this.el.object3D.visible = true - + const term = this.term = new Terminal({ allowTransparency: this.data.transparent, cursorBlink: true, disableStdin: false, rows: this.data.rows, cols: this.data.cols, - fontSize: 64 + fontSize: 16 }) term.open(this.el.dom) @@ -49,14 +47,10 @@ AFRAME.registerComponent('isoterminal', { this.cursorCanvas = this.el.dom.querySelector('.xterm-cursor-layer') - this.el.setAttribute('material', 'transparent', this.data.transparent ) - this.el.setAttribute('material', 'src', '#' + this.canvas.id) + //this.el.setAttribute('material', `transparent: ${this.data.transparent?'true':'false'}; src: #${this.canvas.id}` ) term.on('refresh', () => { - const material = this.el.getObject3D('mesh').material - if (!material.map) return - this.canvasContext.drawImage(this.cursorCanvas, 0,0) - material.map.needsUpdate = true + console.log("refresh") }) term.on('data', (data) => { @@ -67,43 +61,42 @@ AFRAME.registerComponent('isoterminal', { term.focus() }) - const message = 'Hello from \x1B[1;3;31mWebVR\x1B[0m !\r\n$ ' + const message = 'Hello from \x1B[1;3;31mWebVR\x1B[0m !\r\n$ ' term.write(message) }, events:{ // combined AFRAME+DOM reactive events - click: function(e){ }, // - keydown: function(e){ }, // + click: function(e){ }, // + keydown: function(e){ }, // - // reactive events for this.data updates + // reactive events for this.data updates myvalue: function(e){ this.el.dom.querySelector('b').innerText = this.data.myvalue }, - ready: function( ){ + ready: function( ){ this.el.dom.style.display = 'none' }, launcher: function(){ this.el.dom.style.display = '' + this.createTerminal() - new WinBox( this.manifest.iso + ' ' + this.manifest.name, { - width: '512px', - height: '256px', + new WinBox( this.manifest.iso + ' ' + this.manifest.name, { + width: window.innerWidth*0.8, + height: window.innerHeight*0.8, x:"center", y:"center", - id: this.el.uid, // important hint for html-mesh + id: this.el.uid, // important hint for html-mesh root: document.querySelector("#overlay"), mount: this.el.dom, - onclose: () => { - if( !confirm('do you want to kill this virtual machine and all its processes?') ) return true + onclose: () => { + if( !confirm('do you want to kill this virtual machine and all its processes?') ) return true this.el.dom.style.display = 'none' return false } }); - this.createTerminal() - }, }, @@ -151,7 +144,7 @@ AFRAME.registerComponent('isoterminal', { } ], "help":` -Helloworld application +Helloworld application This is a help file which describes the application. It will be rendered thru troika text, and will contain diff --git a/app/launcher.js b/app/launcher.js index acd034f..170e2e5 100644 --- a/app/launcher.js +++ b/app/launcher.js @@ -1,27 +1,27 @@ /* - * ## launcher + * ## launcher * * displays app (icons) for enduser to launch * * ```javascript * * ``` - * + * * | property | type | example | * |--------------|--------------------|----------------------------------------------------------------------------------------| - * | `registries` | `array` of strings | | + * | `registries` | `array` of strings | | * * | event | target | info | * |--------------|-------------------------------------------------------------------------------------------------------------| - * | `launcher` | an app | when pressing an app icon, `launcher` event will be send to the respective app | + * | `launcher` | an app | when pressing an app icon, `launcher` event will be send to the respective app | */ AFRAME.registerComponent('launcher', { - schema: { + schema: { foo: { type:"string"} }, - init: function () { + init: function () { this.data.apps = [] AFRAME.scenes.map( (scene) => { @@ -40,47 +40,53 @@ AFRAME.registerComponent('launcher', {
`, - css: `#iconmenu { + css: (me) => `#iconmenu { z-index: 1000; display: flex; - flex-direction: column-reverse; - align-items: flex-end; - height: 100%; + flex-direction: row; + align-items: flex-start; + height: 50px; + overflow:hidden; position: fixed; - top: 0px; - right: 20px; - bottom: 0; - padding-bottom: 72px; + right: 162px; + bottom: 0px; + left:20px; + background: transparent; + padding-bottom: 54px; box-sizing: border-box; pointer-events: none; visibility: visible !important; } #iconmenu > button { + line-height:0px; pointer-events:all; width: 58px; - height: 39px; - padding: 12px 0px 20px 0px; + height: 34px; + padding: 12px 0px 12px 0px; border-radius: 0px; color: var(--xrsh-primary); background: #FFF; - border-left: 5px solid var(--xrsh-primary); - border-right: 5px solid var(--xrsh-primary); + border-top: 2px solid #BBB; + border-bottom: 2px solid #BBB; + font-size:18px; } #iconmenu > button:first-child { - border-radius:0px 0px 30px 30px; - border-bottom: 5px solid var(--xrsh-primary); - padding-bottom:35px; + border-radius: 5px 0px 0px 5px; + border-bottom: 2px solid #BBB; + border-left: 2px solid #BBB; + padding-bottom:16px; } #iconmenu > button:last-child { - border-radius:30px 30px 0px 0px; - border-top: 5px solid var(--xrsh-primary); + border-radius:0px 5px 5px 0px; + border-top: 2px solid #BBB; + border-right: 2px solid #BBB; padding-top:13px; } #iconmenu > button > img { - transform: translate(0px,-5px); + transform: translate(0px,-14px); opacity:0.5; padding: 5px; border-radius: 0px; @@ -95,12 +101,12 @@ AFRAME.registerComponent('launcher', { events:{ // combined AFRAME+DOM reactive events - click: function(e){ + click: function(e){ console.dir(e) - }, // + }, // - ready: function( ){ + ready: function( ){ this.el.dom.children[0].id = this.el.uid // important hint for html-mesh }, @@ -109,27 +115,36 @@ AFRAME.registerComponent('launcher', { render: function(app){ clearTimeout(this.timeout) this.timeout = setTimeout( () => { - AFRAME.app.foreach( (app) => { - if( !app.manifest ) return - + const drawButton = (app) => { + if( !app.manifest ) return console.log(app.data.uri+" "+app.data.order) - let btn = app.btn = document.createElement('button') if( app.manifest.icons?.length > 0){ - let img = document.createElement('img') + let img = document.createElement('img') img.src = app.manifest.icons[0].src img.title = app.manifest.name + ": " + app.manifest.description btn.appendChild(img) }else btn.innerText = app.manifest.short_name - btn.addEventListener('click', () => app.el.emit('launcher',app) ) + btn.addEventListener('click', () => { + app.el.emit('launcher',app) + app.el.sceneEl.emit('launched',app) + }) this.el.dom.querySelector('#iconmenu').appendChild(btn) - }) + } + + const drawCategory = (app,c) => app.manifest && + app.manifest.short_name != "launcher" && + app.manifest.category == c ? drawButton(app) : false + + AFRAME.app.foreach( (app) => drawCategory(app,undefined) ) + AFRAME.app.foreach( (app) => drawCategory(app,"system") ) + },100) }, manifest: { // HTML5 manifest to identify app to xrsh - "short_name": "Hello world", - "name": "Hello world", + "short_name": "launcher", + "name": "App Launcher", "icons": [ { "src": "https://css.gg/browser.svg", @@ -137,6 +152,7 @@ AFRAME.registerComponent('launcher', { "sizes": "512x512" } ], + "category":"system", "id": "/?source=pwa", "start_url": "/?source=pwa", "background_color": "#3367D6", @@ -169,7 +185,7 @@ AFRAME.registerComponent('launcher', { } ], "help":` -Helloworld application +Helloworld application This is a help file which describes the application. It will be rendered thru troika text, and will contain diff --git a/app/manual.js b/app/manual.js index 38f6ed5..f044d7a 100644 --- a/app/manual.js +++ b/app/manual.js @@ -35,7 +35,7 @@ AFRAME.registerComponent('manual', { `, - css: `.manual > div { padding:11px }` + css: (me) => `.manual > div { padding:11px }` }, events:{ diff --git a/app/spatialize.js b/app/spatialize.js index 18bc533..2da2aec 100644 --- a/app/spatialize.js +++ b/app/spatialize.js @@ -1,5 +1,5 @@ AFRAME.registerComponent('spatialize', { - schema: { + schema: { foo: { type:"string"} }, @@ -7,8 +7,8 @@ AFRAME.registerComponent('spatialize', { document.querySelector('a-scene').addEventListener('enter-vr',() => this.toggle(true) ) document.querySelector('a-scene').addEventListener('exit-vr', () => this.toggle(false) ) - // toggle immersive with ESCAPE - document.body.addEventListener('keydown', (e) => e.key == 'Escape' && this.toggle() ) + // toggle immersive with ESCAPE + document.body.addEventListener('keydown', (e) => e.key == 'Escape' && this.toggle() ) document.head.innerHTML += `` + + this.el.sceneEl.addEventListener('launched',(e) => { + console.dir(e) + let appEl = e.detail.el.dom + if( appEl.style.display != 'none' && appEl.innerHTML ){ + this.btn.style.display = '' // show button + } + }) }, requires:{ @@ -30,7 +38,9 @@ AFRAME.registerComponent('spatialize', { // component events ready: function(e){ + this.btn.style.display = 'none' this.btn.style.background = 'var(--xrsh-primary)' + this.btn.style.color = '#FFF' }, launcher: function(e){ this.toggle() }, @@ -41,28 +51,21 @@ AFRAME.registerComponent('spatialize', { toggle: function(state){ state = state || !document.body.className.match(/XR/) document.body.classList[ state ? 'add' : 'remove'](['XR']) - AFRAME.scenes[0].emit( state ? 'apps:XR' : 'apps:2D') - this.btn.querySelector('img').src = state ? this.manifest.icons[0].src_2D - : this.manifest.icons[0].src + AFRAME.scenes[0].emit( state ? 'apps:XR' : 'apps:2D') + this.btn.innerHTML = state ? "2D" : "2D" }, manifest: { // HTML5 manifest to identify app to xrsh - "short_name": "spatialize", + "short_name": "2D", "name": "spatialize", - "icons": [ - { - "src": "https://css.gg/display-grid.svg", - "src_2D": "https://css.gg/stack.svg", - "type": "image/svg+xml", - "sizes": "512x512" - } - ], + "icons": [], "id": "/?source=pwa", "start_url": "/?source=pwa", "background_color": "#3367D6", "display": "standalone", "scope": "/", "theme_color": "#3367D6", + "category":"system", "shortcuts": [ { "name": "What is the latest news?", @@ -89,7 +92,7 @@ AFRAME.registerComponent('spatialize', { } ], "help":` -Helloworld application +Helloworld application This is a help file which describes the application. It will be rendered thru troika text, and will contain diff --git a/app/vconsole.js b/app/vconsole.js index 99b96c0..2a4ec5b 100644 --- a/app/vconsole.js +++ b/app/vconsole.js @@ -33,6 +33,7 @@ AFRAME.registerComponent('vconsole', { }, launcher: function(){ + if( !this.vConsole ) return let panel = document.querySelector('.vc-panel') if( panel.style.display == 'none' ) this.vConsole.show() else this.vConsole.hide() diff --git a/com/app.js b/com/app.js index c79af2b..3383b6d 100644 --- a/com/app.js +++ b/com/app.js @@ -188,7 +188,7 @@ AFRAME.AComponent.prototype.updateProperties = function(updateProperties){ addCSS: () => { if( this.dom.css && !document.head.querySelector(`style#${this.attrName}`) ){ - document.head.innerHTML += `` + document.head.innerHTML += `` } return tasks },