window-buttons in XR
This commit is contained in:
parent
2b3c41fa6e
commit
55883df288
6 changed files with 57 additions and 24 deletions
|
|
@ -50,9 +50,9 @@ if( !AFRAME.components.dom ){
|
||||||
|
|
||||||
this
|
this
|
||||||
.ensureOverlay()
|
.ensureOverlay()
|
||||||
.addCSS()
|
|
||||||
.createReactiveDOMElement()
|
.createReactiveDOMElement()
|
||||||
.assignUniqueID()
|
.assignUniqueID()
|
||||||
|
.addCSS()
|
||||||
.scaleDOMvsXR()
|
.scaleDOMvsXR()
|
||||||
.triggerKeyboardForInputs()
|
.triggerKeyboardForInputs()
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -41,7 +41,8 @@ AFRAME.registerComponent('helloworld-window', {
|
||||||
-->
|
-->
|
||||||
</div>`,
|
</div>`,
|
||||||
|
|
||||||
css: (me) => `.htmlform { padding:11px; }`
|
css: (me) => `.htmlform { padding:11px; }
|
||||||
|
`
|
||||||
|
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
@ -67,11 +68,16 @@ AFRAME.registerComponent('helloworld-window', {
|
||||||
myvalue: function(e){ this.el.dom.querySelector('#myvalue').innerText = this.data.myvalue },
|
myvalue: function(e){ this.el.dom.querySelector('#myvalue').innerText = this.data.myvalue },
|
||||||
|
|
||||||
launcher: async function(){
|
launcher: async function(){
|
||||||
let s = await AFRAME.utils.require(this.requires)
|
if( !this.el.getAttribute("dom") ){
|
||||||
|
let s = await AFRAME.utils.require(this.requires)
|
||||||
|
|
||||||
// instance this component
|
// instance this component
|
||||||
this.el.setAttribute("dom", "")
|
this.el.setAttribute("dom", "")
|
||||||
this.el.object3D.quaternion.copy( AFRAME.scenes[0].camera.quaternion ) // face towards camera
|
this.el.object3D.quaternion.copy( AFRAME.scenes[0].camera.quaternion ) // face towards camera
|
||||||
|
}else{
|
||||||
|
// toggle visibility
|
||||||
|
this.el.winbox[ this.el.winbox.min ? 'restore' : 'minimize' ]()
|
||||||
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
DOMready: function(){
|
DOMready: function(){
|
||||||
|
|
|
||||||
|
|
@ -13,6 +13,7 @@
|
||||||
*
|
*
|
||||||
* | property | type | default | info |
|
* | property | type | default | info |
|
||||||
* |-------------------|-----------|------------------------|------|
|
* |-------------------|-----------|------------------------|------|
|
||||||
|
* | `title` | `string` | 'xrsh.iso' | window title |
|
||||||
* | `iso` | `string` | https`//forgejo.isvery.ninja/assets/xrsh-buildroot/main/xrsh.iso" | |
|
* | `iso` | `string` | https`//forgejo.isvery.ninja/assets/xrsh-buildroot/main/xrsh.iso" | |
|
||||||
* | `overlayfs` | `string` | '' | zip URL/file to autoextract on top of filesystem |
|
* | `overlayfs` | `string` | '' | zip URL/file to autoextract on top of filesystem |
|
||||||
* | `width` | `number` | 800 ||
|
* | `width` | `number` | 800 ||
|
||||||
|
|
@ -72,6 +73,7 @@ if( typeof AFRAME != 'undefined '){
|
||||||
schema: {
|
schema: {
|
||||||
iso: { type:"string", "default":"https://forgejo.isvery.ninja/assets/xrsh-buildroot/main/xrsh.iso" },
|
iso: { type:"string", "default":"https://forgejo.isvery.ninja/assets/xrsh-buildroot/main/xrsh.iso" },
|
||||||
overlayfs: { type:"string"},
|
overlayfs: { type:"string"},
|
||||||
|
title: { type:"string", "default":"xrsh.iso"},
|
||||||
width: { type: 'number',"default": 800 },
|
width: { type: 'number',"default": 800 },
|
||||||
height: { type: 'number',"default": 600 },
|
height: { type: 'number',"default": 600 },
|
||||||
depth: { type: 'number',"default": 0.03 },
|
depth: { type: 'number',"default": 0.03 },
|
||||||
|
|
@ -142,6 +144,7 @@ if( typeof AFRAME != 'undefined '){
|
||||||
|
|
||||||
.isoterminal{
|
.isoterminal{
|
||||||
padding: ${me.com.data.padding}px;
|
padding: ${me.com.data.padding}px;
|
||||||
|
margin-top:-60px;
|
||||||
width:100%;
|
width:100%;
|
||||||
height:99%;
|
height:99%;
|
||||||
resize: both;
|
resize: both;
|
||||||
|
|
@ -244,18 +247,19 @@ if( typeof AFRAME != 'undefined '){
|
||||||
-webkit-animation:none;
|
-webkit-animation:none;
|
||||||
}
|
}
|
||||||
|
|
||||||
.wb-body:has(> .isoterminal){
|
.winbox#${me.el.uid} .wb-header{
|
||||||
background: #000C;
|
background: var(--xrsh-black) !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.wb-body:has(> .isoterminal){
|
||||||
|
background: var(--xrsh-black);
|
||||||
overflow:hidden;
|
overflow:hidden;
|
||||||
}
|
}
|
||||||
|
|
||||||
.XR .wb-body:has(> .isoterminal){
|
.XR .isoterminal{
|
||||||
background: transparent;
|
background: transparent;
|
||||||
}
|
}
|
||||||
|
|
||||||
.XR .isoterminal{
|
|
||||||
background: #000;
|
|
||||||
}
|
|
||||||
.isoterminal *{
|
.isoterminal *{
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
font-family: "Cousine",Liberation Mono,DejaVu Sans Mono,Courier New,monospace;
|
font-family: "Cousine",Liberation Mono,DejaVu Sans Mono,Courier New,monospace;
|
||||||
|
|
@ -342,7 +346,7 @@ if( typeof AFRAME != 'undefined '){
|
||||||
this.term.emit('term_init', {instance, aEntity:this})
|
this.term.emit('term_init', {instance, aEntity:this})
|
||||||
//instance.winbox.resize(720,380)
|
//instance.winbox.resize(720,380)
|
||||||
let size = `width: ${this.data.width}; height: ${this.data.height}`
|
let size = `width: ${this.data.width}; height: ${this.data.height}`
|
||||||
instance.setAttribute("window", `title: xrsh.iso; uid: ${instance.uid}; attach: #overlay; dom: #${instance.dom.id}; ${size}; min: ${this.data.minimized}; max: ${this.data.maximized}; class: no-full, no-max, no-resize; grabbable: components.html.el.object3D.children.${this.el.children.length}`)
|
instance.setAttribute("window", `title: ${this.data.title}; uid: ${instance.uid}; attach: #overlay; dom: #${instance.dom.id}; ${size}; min: ${this.data.minimized}; max: ${this.data.maximized}; class: no-full, no-close, no-max, no-resize; grabbable: components.html.el.object3D.children.${this.el.children.length}`)
|
||||||
})
|
})
|
||||||
|
|
||||||
instance.addEventListener('window.oncreate', (e) => {
|
instance.addEventListener('window.oncreate', (e) => {
|
||||||
|
|
|
||||||
|
|
@ -17,14 +17,18 @@ function ISOTerminal(instance,opts){
|
||||||
|
|
||||||
ISOTerminal.prototype.emit = function(event,data,sender){
|
ISOTerminal.prototype.emit = function(event,data,sender){
|
||||||
data = data || false
|
data = data || false
|
||||||
// *TODO* wrap certain events into this.preventFrameDrop( () => { .. }) to boost performance
|
|
||||||
const evObj = new CustomEvent(event, {detail: data} )
|
const evObj = new CustomEvent(event, {detail: data} )
|
||||||
// forward event to worker/instance/AFRAME element or component-function
|
// forward event to worker/instance/AFRAME element or component-function
|
||||||
// this feels complex, but actually keeps event- and function-names more concise in codebase
|
// this feels complex, but actually keeps event- and function-names more concise in codebase
|
||||||
this.dispatchEvent( evObj )
|
let fire = () => {
|
||||||
if( sender != "instance" && this.instance ) this.instance.dispatchEvent(evObj)
|
this.dispatchEvent( evObj )
|
||||||
if( sender != "worker" && this.worker ) this.worker.postMessage({event,data}, PromiseWorker.prototype.getTransferable(data) )
|
if( sender != "instance" && this.instance ) this.instance.dispatchEvent(evObj)
|
||||||
if( sender !== undefined && typeof this[event] == 'function' ) this[event].apply(this, data && data.push ? data : [data] )
|
if( sender != "worker" && this.worker ) this.worker.postMessage({event,data}, PromiseWorker.prototype.getTransferable(data) )
|
||||||
|
if( sender !== undefined && typeof this[event] == 'function' ) this[event].apply(this, data && data.push ? data : [data] )
|
||||||
|
}
|
||||||
|
if( event.match(/^serial/) ){
|
||||||
|
this.preventFrameDrop( fire )
|
||||||
|
}else fire()
|
||||||
}
|
}
|
||||||
|
|
||||||
ISOTerminal.addEventListener = (event,cb) => {
|
ISOTerminal.addEventListener = (event,cb) => {
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,8 @@
|
||||||
ISOTerminal.prototype.redirectConsole = function(handler){
|
ISOTerminal.prototype.redirectConsole = function(handler){
|
||||||
const log = console.log;
|
const log = console._log = console.log;
|
||||||
const dir = console.dir;
|
const dir = console._dir = console.dir;
|
||||||
const err = console.error;
|
const err = console._error = console.error;
|
||||||
const warn = console.warn;
|
const warn = console._warn = console.warn;
|
||||||
const addLineFeeds = (str) => typeof str == 'string' ? str.replace(/\n/g,"\r\n") : str
|
const addLineFeeds = (str) => typeof str == 'string' ? str.replace(/\n/g,"\r\n") : str
|
||||||
|
|
||||||
console.log = (...args)=>{
|
console.log = (...args)=>{
|
||||||
|
|
@ -37,12 +37,13 @@ ISOTerminal.prototype.enableConsole = function(opts){
|
||||||
let _str = typeof str == 'string' ? str : JSON.stringify(str)
|
let _str = typeof str == 'string' ? str : JSON.stringify(str)
|
||||||
let finalStr = "";
|
let finalStr = "";
|
||||||
prefix = prefix ? prefix+' ' : ''
|
prefix = prefix ? prefix+' ' : ''
|
||||||
_str.trim().split("\n").map( (line) => {
|
String(_str).trim().split("\n").map( (line) => {
|
||||||
finalStr += `${opts.stdout ? '' : "\x1b[38;5;165m/dev/browser: \x1b[0m"}`+prefix+line+'\n'
|
finalStr += `${opts.stdout ? '' : "\x1b[38;5;165m/dev/browser: \x1b[0m"}`+prefix+line+'\n'
|
||||||
})
|
})
|
||||||
if( opts.stdout ){
|
if( opts.stdout ){
|
||||||
this.emit('serial-output-string', finalStr)
|
this.emit('serial-output-string', finalStr, "worker")
|
||||||
}else this.emit('append_file', ["/dev/browser/console",finalStr])
|
}else this.emit('append_file', ["/dev/browser/console",finalStr])
|
||||||
|
this.lastStr = finalStr
|
||||||
})
|
})
|
||||||
|
|
||||||
window.addEventListener('error', function(event) {
|
window.addEventListener('error', function(event) {
|
||||||
|
|
|
||||||
|
|
@ -91,6 +91,8 @@ AFRAME.registerComponent('window', {
|
||||||
this.el.components['obb-collider'].data.trackedObject3D = this.data.grabbable
|
this.el.components['obb-collider'].data.trackedObject3D = this.data.grabbable
|
||||||
this.el.components['obb-collider'].update()
|
this.el.components['obb-collider'].update()
|
||||||
},1000)
|
},1000)
|
||||||
|
|
||||||
|
this.patchButtons(e)
|
||||||
},
|
},
|
||||||
onclose: close
|
onclose: close
|
||||||
|
|
||||||
|
|
@ -112,7 +114,23 @@ AFRAME.registerComponent('window', {
|
||||||
|
|
||||||
show: function(state){
|
show: function(state){
|
||||||
this.el.dom.closest('.winbox').style.display = state ? '' : 'none'
|
this.el.dom.closest('.winbox').style.display = state ? '' : 'none'
|
||||||
|
},
|
||||||
|
|
||||||
|
// the buttons don't work in XR because HTMLMesh does not understand onclick on divs
|
||||||
|
patchButtons: function(e){
|
||||||
|
let wEl = e.mount;
|
||||||
|
let controls = [...wEl.closest(".winbox").querySelectorAll(".wb-control span")]
|
||||||
|
controls.map( (c) => {
|
||||||
|
if( c.className == "wb-close"){
|
||||||
|
let btn = document.createElement("button")
|
||||||
|
btn.className = "xr-close"
|
||||||
|
btn.innerText = "x"
|
||||||
|
btn.addEventListener("click", (e) => { } )// this will bubble up (to click ancestor in XR)
|
||||||
|
c.appendChild(btn)
|
||||||
|
}
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
})
|
})
|
||||||
|
|
||||||
AFRAME.utils.positionObjectNextToNeighbor = function positionObjectNextToNeighbor(object, lastNeighbor = null, margin ){
|
AFRAME.utils.positionObjectNextToNeighbor = function positionObjectNextToNeighbor(object, lastNeighbor = null, margin ){
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue