diff --git a/com/dom.js b/com/dom.js
index cac678c..c16f90f 100644
--- a/com/dom.js
+++ b/com/dom.js
@@ -95,7 +95,7 @@ AFRAME.registerComponent('dom',{
assignUniqueID: function(){
// assign unique app id so it's easy to reference (by html-mesh component e.g.)
- if( !this.el.uid ) this.el.uid = '_'+String(Math.random()).substr(10)
+ if( !this.el.uid ) this.el.uid = this.el.dom.id = '_'+String(Math.random()).substr(10)
return this
},
diff --git a/com/isoterminal.js b/com/isoterminal.js
index aedb234..6868bdb 100644
--- a/com/isoterminal.js
+++ b/com/isoterminal.js
@@ -11,6 +11,7 @@ AFRAME.registerComponent('isoterminal', {
},
requires:{
+ 'window': "com/window.js",
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", //
@@ -21,11 +22,11 @@ AFRAME.registerComponent('isoterminal', {
},
dom: {
- scale: 3,
+ scale: 0.7,
events: ['click','keydown'],
html: (me) => `
`,
css: (me) => `.isoterminal{
@@ -44,48 +45,6 @@ AFRAME.registerComponent('isoterminal', {
}`
},
- createTerminal: async function(instance){
- const dom = instance.dom
- //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: 16
- })
-
- term.open(dom)
- this.canvas = dom.querySelector('.xterm-text-layer')
- this.canvas.id = 'terminal-' + instance.uid
- this.canvasContext = this.canvas.getContext('2d')
-
- this.cursorCanvas = dom.querySelector('.xterm-cursor-layer')
-
- //this.el.setAttribute('material', `transparent: ${this.data.transparent?'true':'false'}; src: #${this.canvas.id}` )
-
- term.on('refresh', () => {
- console.log("refresh")
- })
-
- term.on('data', (data) => {
- console.log(data)
- this.el.emit('xterm-data', data)
- })
-
- this.el.addEventListener('click', () => {
- term.focus()
- })
-
- const message = 'Hello from \x1B[1;3;31mWebVR\x1B[0m !\r\n$ '
- term.write(message)
-
- this.runISO()
- return {width: this.canvas.width, height: this.canvas.height }
- },
-
runISO: function(dom){
var emulator = window.emulator = new V86({
wasm_path: "com/isoterminal/v86.wasm",
@@ -102,12 +61,12 @@ AFRAME.registerComponent('isoterminal', {
cdrom: {
url: this.data.iso,
},
+ network_relay_url: "",
+ cmdline: "rw root=host9p rootfstype=9p rootflags=trans=virtio,cache=loose modules=virtio_pci tsc=reliable init_on_free=on",
//bzimage:{
// url: "com/isoterminal/images/buildroot-bzimage.bin"
//},
- network_relay_url: "",
//bzimage_initrd_from_filesystem: true,
- cmdline: "rw root=host9p rootfstype=9p rootflags=trans=virtio,cache=loose modules=virtio_pci tsc=reliable init_on_free=on",
//filesystem: {
// baseurl: "com/isoterminal/v86/images/alpine-rootfs-flat",
// basefs: "com/isoterminal/v86/images/alpine-fs.json",
@@ -135,56 +94,23 @@ AFRAME.registerComponent('isoterminal', {
// instance this component
const instance = this.el.cloneNode(false)
this.el.sceneEl.appendChild( instance )
-// instance.addEventListener('DOMready', () => {
-// console.dir(instance)
-// debugger
-// this.runISO(instance.dom)
-// })
+
+ instance.addEventListener('DOMready', () => {
+ this.runISO(instance.dom)
+ instance.setAttribute("window", `title: ${this.data.iso}; uid: ${instance.uid}; attach: #overlay; dom: #${instance.dom.id}`)
+ })
+
+ instance.addEventListener('window.onclose', (e) => {
+ if( !confirm('do you want to kill this virtual machine and all its processes?') ) e.halt = true
+ })
+
instance.setAttribute("dom", "")
instance.setAttribute("xd", "") // allows flipping between DOM/WebGL when toggling XD-button
instance.setAttribute("visible", AFRAME.utils.XD() == '3D' ? 'true' : 'false' )
instance.setAttribute("position", AFRAME.utils.XD.getPositionInFrontOfCamera(0.5) )
- // instance.setAttribute("grabbable","")
+ instance.setAttribute("grabbable","")
+
instance.object3D.quaternion.copy( AFRAME.scenes[0].camera.quaternion ) // face towards camera
-
- const setupWindow = () => {
- this.runISO(instance.dom)
- const com = instance.components['isoterminal']
- instance.dom.style.display = 'none'
- let winbox = new WinBox( this.data.iso, {
- height:'50px',
- x:"center",
- y:"center",
- id: instance.uid, // important hint for html-mesh
- root: document.querySelector("#overlay"),
- mount: instance.dom,
- onclose: () => {
- if( !confirm('do you want to kill this virtual machine and all its processes?') ) return true
- instance.dom.style.display = 'none';
- return false
- },
- oncreate: () => {
- setTimeout( () => {
- winbox.resize( winbox.width+'px', (instance.dom.offsetHeight+(2*15))+'px' )
- setTimeout( () => instance.setAttribute("html",`html:#${instance.uid}; cursor:#cursor`), 1000)
- },100)
- }
- });
- instance.dom.style.display = '' // show
-
- // hint grabbable's obb-collider to track the window-object
- instance.components['obb-collider'].data.trackedObject3D = 'components.html.el.object3D.children.0'
- instance.components['obb-collider'].update()
-
- // data2event demo
- //instance.setAttribute("data2event","")
- //com.data.myvalue = 1
- //com.data.foo = `instance ${instance.uid}: `
- //setInterval( () => com.data.myvalue++, 500 )
- }
-
- setTimeout( () => setupWindow(), 10 ) // give new components time to init
-
},
},
@@ -242,29 +168,3 @@ in above's case "\nHelloworld application\n" will qualify as header.
}
});
-
-AFRAME.registerComponent('xterm-shell', {
- dependencies: ['xterm'],
- init: function() {
- const message = 'Run \x1B[1;3;31m\'node server.js\'\x1B[0m to open a shell\r\n'
- const xterm = this.el.components['xterm']
-
- xterm.write(message)
-
- const socket = new WebSocket('ws://localhost:8080/')
-
- // Listen on data, write it to the terminal
- socket.onmessage = ({data}) => {
- xterm.write(data)
- }
-
- socket.onclose = () => {
- xterm.write('\r\nConnection closed.\r\n')
- }
-
- // Listen on user input, send it to the connection
- this.el.addEventListener('xterm-data', ({detail}) => {
- socket.send(detail)
- })
- }
-})
diff --git a/com/launcher.js b/com/launcher.js
index b62ff67..26aa254 100644
--- a/com/launcher.js
+++ b/com/launcher.js
@@ -80,8 +80,8 @@ AFRAME.registerComponent('launcher', {
dom: {
scale: 3,
events: ['click'],
- html: (me) => ``,
- css: (me) => `#iconmenu {
+ html: (me) => ``,
+ css: (me) => `.iconmenu {
z-index: 1000;
display: flex;
flex-direction: row;
@@ -98,7 +98,7 @@ AFRAME.registerComponent('launcher', {
pointer-events: none;
visibility: visible !important;
}
- #iconmenu > button {
+ .iconmenu > button {
line-height:0px;
pointer-events:all;
width: 58px;
@@ -112,27 +112,27 @@ AFRAME.registerComponent('launcher', {
font-size:18px;
}
- #iconmenu > button:first-child {
+ .iconmenu > button:first-child {
border-radius: 5px 0px 0px 5px;
border-bottom: 2px solid #BBB;
border-left: 2px solid #BBB;
padding-bottom:16px;
}
- #iconmenu > button:last-child {
+ .iconmenu > button:last-child {
border-radius:0px 5px 5px 0px;
border-top: 2px solid #BBB;
border-right: 2px solid #BBB;
padding-top:13px;
}
- #iconmenu > button > img {
+ .iconmenu > button > img {
transform: translate(0px,-14px);
opacity:0.5;
padding: 5px;
border-radius: 0px;
}
- #iconmenu > button > img:hover{
+ .iconmenu > button > img:hover{
background: #AAA;
transition:0.gg3s;
border-radius: 50%;
diff --git a/com/window.js b/com/window.js
new file mode 100644
index 0000000..fac3780
--- /dev/null
+++ b/com/window.js
@@ -0,0 +1,55 @@
+AFRAME.registerComponent('window', {
+ schema:{
+ title: {type:'string',"default":"title"},
+ width: {type:'string'}, // wrap
+ height: {type:'string',"default":'50px'},
+ uid: {type:'string'},
+ attach: {type:'selector'},
+ dom: {type:'selector'},
+ x: {type:'string',"default":"center"},
+ y: {type:'string',"default":"center"}
+ },
+
+ dependencies:['dom'],
+
+ init: function(){
+ setTimeout( () => this.setupWindow(), 10 ) // init after other components
+ },
+
+ setupWindow: function(){
+ if( !this.el.dom ) return console.error('window element requires dom-component as dependency')
+
+ this.el.dom.style.display = 'none'
+ let winbox = new WinBox( this.data.title, {
+ height:this.data.height,
+ height:this.data.width,
+ x: this.data.x,
+ y: this.data.y,
+ id: this.data.uid || String(Math.random()).substr(4), // important hint for html-mesh
+ root: this.data.attach || document.body,
+ mount: this.data.dom,
+ oncreate: () => {
+ this.el.emit('window.oncreate',{})
+ // resize after the dom content has been rendered & updated
+ setTimeout( () => {
+ winbox.resize( winbox.width+'px', (this.data.dom.offsetHeight+(2*15))+'px' )
+ setTimeout( () => this.el.setAttribute("html",`html:#${this.data.uid}; cursor:#cursor`), 1000)
+ this.el.setAttribute("grabbable","")
+ },1000)
+ },
+ onclose: () => {
+ let e = {halt:false}
+ this.el.emit('window.onclose',e)
+ if( e.halt ) return true
+ this.data.dom.style.display = 'none';
+ return false
+ },
+ });
+ this.data.dom.style.display = '' // show
+
+ // hint grabbable's obb-collider to track the window-object
+ this.el.components['obb-collider'].data.trackedObject3D = 'components.html.el.object3D.children.0'
+ this.el.components['obb-collider'].update()
+
+ }
+})