make cursor visible in XR too
/ mirror_to_github (push) Successful in 44s Details
/ test (push) Successful in 6s Details

This commit is contained in:
Leon van Kammen 2024-10-24 14:24:51 +00:00
parent 9e6ea795d5
commit bf9aca6d00
3 changed files with 531 additions and 502 deletions

View File

@ -21,7 +21,7 @@ if( !AFRAME.components['html-as-texture-in-xr'] ){
this.el.setAttribute("html",`html: ${this.data.domid}; cursor:#cursor; xrlayer: true`) this.el.setAttribute("html",`html: ${this.data.domid}; cursor:#cursor; xrlayer: true`)
this.el.setAttribute("visible", AFRAME.utils.XD() == '3D' ? 'true' : 'false' ) this.el.setAttribute("visible", AFRAME.utils.XD() == '3D' ? 'true' : 'false' )
if( this.data.faceuser ){ if( this.data.faceuser ){
this.el.setAttribute("position", AFRAME.utils.XD.getPositionInFrontOfCamera(0.8) ) this.el.setAttribute("position", AFRAME.utils.XD.getPositionInFrontOfCamera(0.4) )
} }
}, },

View File

@ -40,7 +40,6 @@ if( typeof AFRAME != 'undefined '){
depth: { type: 'number',"default": 0.03 }, depth: { type: 'number',"default": 0.03 },
lineHeight: { type: 'number',"default": 18 }, lineHeight: { type: 'number',"default": 18 },
padding: { type: 'number',"default": 18 }, padding: { type: 'number',"default": 18 },
minimized: { type: 'boolean',"default":false},
maximized: { type: 'boolean',"default":true}, maximized: { type: 'boolean',"default":true},
muteUntilPrompt:{ type: 'boolean',"default":true}, // mute stdout until a prompt is detected in ISO muteUntilPrompt:{ type: 'boolean',"default":true}, // mute stdout until a prompt is detected in ISO
HUD: { type: 'boolean',"default":false}, // link to camera movement HUD: { type: 'boolean',"default":false}, // link to camera movement
@ -97,11 +96,11 @@ if( typeof AFRAME != 'undefined '){
css: (me) => `.isoterminal{ css: (me) => `.isoterminal{
padding: ${me.com.data.padding}px; padding: ${me.com.data.padding}px;
width:100%; width:100%;
height:100%; height:90%;
position:relative; position:relative;
} }
.isoterminal div{ .isoterminal div{
display:block; display:inline-block;
position:relative; position:relative;
line-height: ${me.com.data.lineHeight}px; line-height: ${me.com.data.lineHeight}px;
} }
@ -133,6 +132,17 @@ if( typeof AFRAME != 'undefined '){
box-shadow:none; box-shadow:none;
} }
.cursor {
background: #70F !important;
animation:fade 1000ms infinite;
-webkit-animation:fade 1000ms infinite;
}
.XR .cursor {
animation:none;
-webkit-animation:none;
}
.wb-body:has(> .isoterminal){ .wb-body:has(> .isoterminal){
background: #000C; background: #000C;
overflow:hidden; overflow:hidden;
@ -259,10 +269,10 @@ if( typeof AFRAME != 'undefined '){
instance.addEventListener('window.onmaximize', resize ) instance.addEventListener('window.onmaximize', resize )
const focus = (showdom) => (e) => { const focus = (showdom) => (e) => {
this.el.emit('focus',e.detail)
if( this.el.components.window && this.data.renderer == 'canvas'){ if( this.el.components.window && this.data.renderer == 'canvas'){
this.el.components.window.show( showdom ) this.el.components.window.show( showdom )
} }
this.el.emit('focus',e.detail)
} }
this.el.addEventListener('obbcollisionstarted', focus(false) ) this.el.addEventListener('obbcollisionstarted', focus(false) )
@ -296,17 +306,18 @@ if( typeof AFRAME != 'undefined '){
cols: this.cols, cols: this.cols,
rows: this.rows, rows: this.rows,
el_or_id: el, el_or_id: el,
max_scroll_lines: 100, max_scroll_lines: this.rows,
nodim: true nodim: true,
rainbow: [VT100.COLOR_MAGENTA, VT100.COLOR_CYAN ],
xr: AFRAME.scenes[0].renderer.xr
} }
this.vt100 = new VT100( opts ) this.vt100 = new VT100( opts )
this.vt100.el = el this.vt100.el = el
this.vt100.curs_set( 1, true) this.vt100.curs_set( 1, true)
el.focus() this.vt100.focus()
this.el.addEventListener('focus', () => el.focus()) this.el.addEventListener('focus', () => this.vt100.focus() )
this.vt100.getch( (ch,t) => { this.vt100.getch( (ch,t) => {
this.term.send( ch ) this.term.send( ch )
this.vt100.curs_set( 0, true)
}) })
this.el.addEventListener('serial-output-byte', (e) => { this.el.addEventListener('serial-output-byte', (e) => {
@ -317,14 +328,6 @@ if( typeof AFRAME != 'undefined '){
this.el.addEventListener('serial-output-string', (e) => { this.el.addEventListener('serial-output-string', (e) => {
this.vt100.write(e.detail) this.vt100.write(e.detail)
}) })
//this.el.dom.querySelector('input').addEventListener('keyup', (e) => {
// VT100.handle_onkeypress_( {charCode : e.charCode || e.keyCode, keyCode: e.keyCode}, (chars) => {
// debugger
// chars.map( (c) => this.term.send(str) )
// })
//})
}, },
setupBox: function(){ setupBox: function(){
@ -339,13 +342,13 @@ if( typeof AFRAME != 'undefined '){
}, },
calculateDimension: function(){ calculateDimension: function(){
if( this.data.width == -1 ) this.data.width = document.body.offsetWidth if( this.data.width == -1 ) this.data.width = document.body.offsetWidth;
if( this.data.height == -1 ) this.data.height = document.body.offsetHeight if( this.data.height == -1 ) this.data.height = Math.floor( document.body.offsetHeight - 30 )
if( this.data.height > this.data.width ) this.data.height = this.data.width // mobile smartphone fix if( this.data.height > this.data.width ) this.data.height = this.data.width // mobile smartphone fix
this.data.width -= this.data.padding*2 this.data.width -= this.data.padding*2
this.data.height -= this.data.padding*2 this.data.height -= this.data.padding*2
this.cols = Math.floor(this.data.width/this.data.lineHeight*1.9) this.cols = Math.floor(this.data.width/this.data.lineHeight*2)
this.rows = Math.floor(this.data.height*0.5/this.data.lineHeight*1.7) // keep extra height for mobile browser bottom-bar (android) this.rows = Math.floor(this.data.height*0.53/this.data.lineHeight*1.7)
}, },
events:{ events:{

View File

@ -13,6 +13,8 @@
// //
// Released under the GNU LGPL v2.1, by Frank Bi <bi@zompower.tk> // Released under the GNU LGPL v2.1, by Frank Bi <bi@zompower.tk>
// //
//
// 2024-08-xx upgraded things to work in WebXR (xterm.js too heavy)
// 2007-08-12 - refresh(): // 2007-08-12 - refresh():
// - factor out colour code to html_colours_() // - factor out colour code to html_colours_()
// - fix handling of A_REVERSE | A_DIM // - fix handling of A_REVERSE | A_DIM
@ -118,6 +120,8 @@ function VT100(opts)
this.redraw_[r] = 1; this.redraw_[r] = 1;
} }
this.scr_ = scr; this.scr_ = scr;
this.scr_.style.display = 'inline'
this.setupTouchInputFallback() // smartphone
this.cursor_vis_ = true; this.cursor_vis_ = true;
this.cursor_key_mode_ = VT100.CK_CURSOR; this.cursor_key_mode_ = VT100.CK_CURSOR;
this.grab_events_ = false; this.grab_events_ = false;
@ -131,8 +135,6 @@ function VT100(opts)
// rate limit this.refresh // rate limit this.refresh
this.refresh = this.throttleSmart( VT100.prototype.refresh.bind(this), 100) this.refresh = this.throttleSmart( VT100.prototype.refresh.bind(this), 100)
this.setupTouchInputFallback() // smartphone
} }
// public constants -- colours and colour pairs // public constants -- colours and colour pairs
@ -552,8 +554,9 @@ VT100.prototype.clearpos = function VT100_clearpos(row, col)
VT100.prototype.curs_set = function(vis, grab, eventist) VT100.prototype.curs_set = function(vis, grab, eventist)
{ {
this.info("curs_set:: vis: " + vis + ", grab: " + grab); this.info("curs_set:: vis: " + vis + ", grab: " + grab);
if (vis !== undefined) if (vis !== undefined){
this.cursor_vis_ = (vis > 0); this.cursor_vis_ = (vis > 0);
}
if (eventist === undefined) if (eventist === undefined)
eventist = this.scr_; eventist = this.scr_;
if (grab === true || grab === false) { if (grab === true || grab === false) {
@ -656,7 +659,8 @@ VT100.prototype.refresh = function VT100_refresh()
for (c = 0; c < wd; ++c) { for (c = 0; c < wd; ++c) {
added_end_tag = false; added_end_tag = false;
n_at = this.attr_[r][c]; n_at = this.attr_[r][c];
if (cv && r == cr && c == cc) { const drawCursor = cv && r == cr && c == cc
if (drawCursor){
// Draw the cursor here. // Draw the cursor here.
n_at = this._cloneAttr(n_at); n_at = this._cloneAttr(n_at);
n_at.mode ^= VT100.A_REVERSE; n_at.mode ^= VT100.A_REVERSE;
@ -681,7 +685,9 @@ VT100.prototype.refresh = function VT100_refresh()
start_tag += ';font-weight: bolder'; start_tag += ';font-weight: bolder';
if (n_at.mode & VT100.A_UNDERLINE) if (n_at.mode & VT100.A_UNDERLINE)
start_tag += ';text-decoration:underline'; start_tag += ';text-decoration:underline';
start_tag += ';">'; if ( drawCursor )
start_tag += '" class="cursor'
start_tag += '">';
row_html += start_tag; row_html += start_tag;
end_tag = "</span>" + end_tag; end_tag = "</span>" + end_tag;
at = n_at; at = n_at;
@ -721,6 +727,7 @@ VT100.prototype.refresh = function VT100_refresh()
div_element.innerHTML = row_html; div_element.innerHTML = row_html;
//dump("adding row html: " + row_html + "\n"); //dump("adding row html: " + row_html + "\n");
} }
this.curs_set(1)
} }
VT100.prototype.set_max_scroll_lines = function(max_lines) VT100.prototype.set_max_scroll_lines = function(max_lines)
@ -1067,6 +1074,10 @@ VT100.prototype.write = function VT100_write(stuff)
case 'm': case 'm':
for (j=0; j<this.csi_parms_.length; ++j) { for (j=0; j<this.csi_parms_.length; ++j) {
x = this.csi_parms_[j]; x = this.csi_parms_[j];
if( x > 89 && x < 98 && this.opts.rainbow ){
const rainbow = this.opts.rainbow
this.fgset( rainbow[ Math.floor( Math.random() * 1000 ) % rainbow.length ] )
}
switch (x) { switch (x) {
case 0: case 0:
this.standend(); this.standend();
@ -1166,6 +1177,7 @@ VT100.prototype.write = function VT100_write(stuff)
default: default:
this.warn(" unknown command: " + ch); this.warn(" unknown command: " + ch);
this.csi_parms_ = []; this.csi_parms_ = [];
return
break; break;
} }
break; break;
@ -1309,38 +1321,52 @@ VT100.prototype.throttleSmart = function throttleSmart(fn, wait) {
} }
VT100.prototype.setupTouchInputFallback = function(){ VT100.prototype.setupTouchInputFallback = function(){
this.scr_.addEventListener('touchend', () => {
if( !this.input ){ if( !this.input ){
this.form = document.createElement("form")
this.form.addEventListener("submit", (e) => {
e.preventDefault()
this.key_buf_.push('\n')
setTimeout(VT100.go_getch_, 0);
})
this.input = document.createElement("input") this.input = document.createElement("input")
this.input.setAttribute("cols", this.opts.cols ) this.input.setAttribute("cols", this.opts.cols )
this.input.setAttribute("rows", this.opts.rows ) this.input.setAttribute("rows", this.opts.rows )
this.input.style.opacity = '0' this.input.style.opacity = '0'
this.input.style.position = 'absolute' this.input.style.position = 'absolute'
this.input.style.left = '-9999px' this.input.style.left = '-9999px'
this.form = document.createElement("form")
this.form.addEventListener("submit", (e) => {
e.preventDefault()
this.key_buf_.push('\n')
setTimeout(VT100.go_getch_, 0);
})
this.form.appendChild(this.input) this.form.appendChild(this.input)
this.scr_.parentElement.appendChild(this.form) this.scr_.parentElement.appendChild(this.form)
this.input.handler = () => { this.input.addEventListener('blur', () => {
let ch = this.input.value this.key_buf_.push('\n')
setTimeout(VT100.go_getch_, 0);
})
this.input.addEventListener("keydown", VT100.handle_onkeypress_, false);
this.input.handler = (e) => {
let ch
let isEnter = String(e?.code).toLowerCase() == "enter" || e?.code == 13
ch = isEnter ? '\n' : this.input.value.substr(-1)
if( this.input.lastValue && this.input.value.length < this.input.lastValue.length ) ch = '\b' // naive
// detect backspace // detect backspace
//if( e.inputType == 'deleteContentBackward' ) ch = '\b'
this.input.value = ''
if( !ch ) return if( !ch ) return
this.key_buf_.push(ch); this.key_buf_.push(ch);
setTimeout(VT100.go_getch_, 0); setTimeout(VT100.go_getch_, 0);
this.input.valueLast = this.input.value this.input.lastValue = this.input.value
} }
this.input.addEventListener('input', this.input.handler ) this.input.addEventListener('input', (e) => this.input.handler(e) )
this.scr_.addEventListener('touchend', (e) => this.focus() )
this.scr_.addEventListener('click', (e) => this.focus() )
} }
setTimeout( () => this.input.focus(), 10 ) this.focus()
}) }
VT100.prototype.focus = function(){
setTimeout( () => {
this.input.focus()
}, 10 )
} }
function dump(x) { function dump(x) {