bz-toggler

This commit is contained in:
STEINNI
2025-10-20 14:33:13 +00:00
parent d0ca65a435
commit 2ff7bf9b8a
11 changed files with 272 additions and 26 deletions
+8
View File
@@ -3,9 +3,17 @@
"error": "", "error": "",
"payload": { "payload": {
"/agents": { "/agents": {
"getTypes": {
"uri": "/api/agent-types/{family}",
"method": "GET"
},
"getSprites": { "getSprites": {
"uri": "/api/agent-sprites/{group}", "uri": "/api/agent-sprites/{group}",
"method": "GET" "method": "GET"
},
"getProperties": {
"uri": "/api/agent/{id}",
"method": "GET"
} }
} }
} }
+7 -1
View File
@@ -331,7 +331,10 @@ menu[eicmenu] [menuitem] a label {
menu[eicmenu] [menuitem] i[class^="icon-"] { menu[eicmenu] [menuitem] i[class^="icon-"] {
color:#fdfb93;; color:#fdfb93;;
} }
article[eiccard] > header h1{ text-align: center; }
/* Customizations to buildoz*/
bz-select > button{ bz-select > button{
background: linear-gradient( to bottom, #251, #372 15%, #483 50%, #372 85%, #251 ) !important; background: linear-gradient( to bottom, #251, #372 15%, #483 50%, #372 85%, #251 ) !important;
color:#EEE; color:#EEE;
@@ -343,4 +346,7 @@ bz-select option{
} }
bz-select option:hover{ bz-select option:hover{
background-color: #493; background-color: #493;
} }
bz-toggler div.toggle-switch span.toggle-bar { background-color: #473; }
bz-toggler div.toggle-switch span.toggle-thumb { background-color:#9D8; }
@@ -6,7 +6,6 @@ class EditorsController extends WindozController {
constructor(params) { constructor(params) {
super(params) super(params)
this.arenaConfig = app.Assets.Store.json.arenaConfig this.arenaConfig = app.Assets.Store.json.arenaConfig
this.agentDefs = app.Assets.Store.json.agentDefs
this.eventsMapping = app.Assets.Store.json.eventsMapping this.eventsMapping = app.Assets.Store.json.eventsMapping
} }
+3 -5
View File
@@ -26,9 +26,9 @@ class DashboardsController extends WindozController {
grid: true, grid: true,
}) })
this.agentDefs = await models.agents.getSprites('Basic 3D') this.agentSprites = await models.agents.getSprites('Basic 3D')
const a1 = ttb.createAgent('agent42', this.agentDefs.nocode1) const a1 = ttb.createAgent('agent42', this.agentSprites.find(item => item.atp_name=='nocode1').atp_3d)
const a2 = ttb.createAgent('agent42', this.agentDefs.nocode2) const a2 = ttb.createAgent('agent42', this.agentSprites.find(item => item.atp_name=='nocode1').atp_3d)
ttb.scene.add(a1) ttb.scene.add(a1)
ttb.scene.add(a2) ttb.scene.add(a2)
@@ -46,7 +46,6 @@ class DashboardsController extends WindozController {
}, },
{ {
models: models, models: models,
agentDefs: this.agentDefs,
rendererId:'3drenderer', rendererId:'3drenderer',
mode: '3D', mode: '3D',
ttb: ttb, ttb: ttb,
@@ -65,7 +64,6 @@ class DashboardsController extends WindozController {
}, },
{ {
models: models, models: models,
agentDefs: this.agentDefs,
rendererId:'2drenderer', rendererId:'2drenderer',
mode: '2D', mode: '2D',
ttb: ttb, ttb: ttb,
+18
View File
@@ -5,6 +5,15 @@ class AgentsModel extends WindozModel {
this.ressource = '/agents' this.ressource = '/agents'
} }
async getTypes(family) {
let endpoint = app.config.api[this.ressource].getTypes
endpoint.uri = endpoint.uri.replace('{family}', family)
return (
this.request(endpoint.uri, endpoint.method)
.then( async serverData => serverData.payload.agentTypes)
)
}
async getSprites(group) { async getSprites(group) {
let endpoint = app.config.api[this.ressource].getSprites let endpoint = app.config.api[this.ressource].getSprites
endpoint.uri = endpoint.uri.replace('{group}', group) endpoint.uri = endpoint.uri.replace('{group}', group)
@@ -13,6 +22,15 @@ class AgentsModel extends WindozModel {
.then( async serverData => serverData.payload.agentSprites) .then( async serverData => serverData.payload.agentSprites)
) )
} }
async getProperties(id) {
let endpoint = app.config.api[this.ressource].getProperties
endpoint.uri = endpoint.uri.replace('{id}', id)
return (
this.request(endpoint.uri, endpoint.method)
.then( async serverData => serverData.payload.agentProperties)
)
}
} }
app.registerClass('AgentsModel', AgentsModel); app.registerClass('AgentsModel', AgentsModel);
+78 -1
View File
@@ -1,6 +1,13 @@
bz-select { bz-select {
display: block; display: block;
margin: .5rem 0 .5rem 0; margin: .5rem 0 .5rem 0;
position:relative;
}
bz-select[disabled] > button{
opacity: 0.6;
cursor: not-allowed;
pointer-events: none;
filter: grayscale(30%);
} }
bz-select > button{ bz-select > button{
width:100%; width:100%;
@@ -16,7 +23,7 @@ bz-select > button::after {
content: "\00BB"; content: "\00BB";
transform: rotate(90deg) translateX(-0.4rem); transform: rotate(90deg) translateX(-0.4rem);
position: absolute; position: absolute;
right: 1.5rem; right: 0.5rem;
pointer-events: none; pointer-events: none;
font-size: 1.5rem; font-size: 1.5rem;
color: #444; color: #444;
@@ -45,4 +52,74 @@ bz-select option.open{
bz-select option:hover{ bz-select option:hover{
background-color: #44F; background-color: #44F;
color: #FFF; color: #FFF;
}
bz-toggler{
outline: none;
min-height: 1.5rem;
padding: 0.75rem !important;
display: inline-table;
max-width: fit-content;
transition: all 0.5s;
}
bz-toggler div.toggle-label-left{
padding-right: 0.3rem;
display: table-cell;
vertical-align: middle;
text-align: right;
font-size:.8rem;
}
bz-toggler div.toggle-label-right{
padding-left: 0.3rem;
display: table-cell;
vertical-align: middle;
text-align: left;
font-size:.8rem;
}
bz-toggler div.toggle-switch{
user-select: none;
height: inherit;
cursor: pointer;
display: table-cell;
vertical-align: middle;
text-align: center;
}
bz-toggler div.toggle-switch span.toggle-bar {
display: inline-block;
position: relative;
background-color: #CCC;
}
bz-toggler div.toggle-switch span.toggle-thumb {
display: inline-block;
border-radius: 50%;
background-color: white;
position: absolute;
z-index: 1;
}
bz-toggler div.toggle-switch span.toggle-thumb:not(.turned-on) {
left: 0;
transition: all 0.4s;
}
bz-toggler div.toggle-switch span.toggle-thumb.turned-on {
transition: all 0.4s;
}
bz-toggler div.toggle-switch span.toggle-bar {
width: 2rem;
height: 0.75rem;
border-radius: .75rem;
}
bz-toggler div.toggle-switch span.toggle-thumb {
height: 1rem;
width: 1rem;
top: -0.1rem;
}
bz-toggler div.toggle-switch span.toggle-thumb.turned-on {
left : 1rem;
} }
+89 -5
View File
@@ -32,6 +32,10 @@ class Buildoz extends HTMLElement {
attributeChangedCallback(name, oldValue, newValue) { attributeChangedCallback(name, oldValue, newValue) {
this.attrs[name] = newValue this.attrs[name] = newValue
} }
getBZAttribute(attrName){ // Little helper for defaults
return(this.getAttribute(attrName) || this.defaultAttrs[attrName] )
}
} }
class BZselect extends Buildoz { class BZselect extends Buildoz {
@@ -47,7 +51,7 @@ class BZselect extends Buildoz {
connectedCallback() { connectedCallback() {
super.connectedCallback() super.connectedCallback()
this.button = document.createElement('button') this.button = document.createElement('button')
this.button.textContent = this.getAttribute('label') || this.defaultAttrs.label this.button.textContent = this.getBZAttribute('label')
this.prepend(this.button) this.prepend(this.button)
this.button.addEventListener('click', this.toggle.bind(this)) this.button.addEventListener('click', this.toggle.bind(this))
this.options = this.querySelectorAll('option') this.options = this.querySelectorAll('option')
@@ -58,9 +62,9 @@ class BZselect extends Buildoz {
} }
// static get observedAttributes(){ // Only if you want actions on attr change // static get observedAttributes(){ // Only if you want actions on attr change
// return([...super.observedAttributes, 'myattr']) // return([...super.observedAttributes, 'disabled'])
// } // }
//
// attributeChangedCallback(name, oldValue, newValue) { // attributeChangedCallback(name, oldValue, newValue) {
// super.attributeChangedCallback(name, oldValue, newValue) // super.attributeChangedCallback(name, oldValue, newValue)
// } // }
@@ -79,11 +83,12 @@ class BZselect extends Buildoz {
} }
onOption(value, silent=false){ onOption(value, silent=false){
if(this.getAttribute('disabled') !== null) return
this.value = value this.value = value
if(!silent) this.toggle() if(!silent) this.toggle()
const opt = Array.from(this.options).find(opt => opt.value==value) const opt = Array.from(this.options).find(opt => opt.value==value)
if(value || (opt && opt.textContent)) this.button.textContent = opt.textContent if(value || (opt && opt.textContent)) this.button.textContent = opt.textContent
else this.button.textContent = this.getAttribute('label') || this.defaultAttrs.label else this.button.textContent = this.getBZAttribute('label')
this.dispatchEvent(new Event('change', { this.dispatchEvent(new Event('change', {
bubbles: true, bubbles: true,
composed: false, composed: false,
@@ -109,5 +114,84 @@ class BZselect extends Buildoz {
for(const opt of opts) this.addOption(opt.value, opt.markup) for(const opt of opts) this.addOption(opt.value, opt.markup)
} }
} }
Buildoz.define('select', BZselect)
Buildoz.define('select', BZselect)
class BZtoggler extends Buildoz {
constructor(){
super()
this.value = null
this.open = false
this.defaultAttrs = {
labelLeft:'',
labelRight:'',
trueValue: 'yes',
falseValue: 'no',
classOn:'',
classOff:'',
tabindex:0,
disabled:false
}
}
connectedCallback(){
super.connectedCallback()
this.labelRight = document.createElement('div')
this.labelRight.classList.add('toggle-label-right')
this.labelRight.innerHTML = this.getBZAttribute('labelRight')
this.labelLeft = document.createElement('div')
this.labelLeft.classList.add('toggle-label-left')
this.labelLeft.innerHTML = this.getBZAttribute('labelLeft')
this.switch = document.createElement('div')
this.switch.classList.add('toggle-switch')
this.toggleBar = document.createElement('span')
this.toggleBar.classList.add('toggle-bar')
this.thumb = document.createElement('span')
this.thumb.classList.add('toggle-thumb')
this.toggleBar.append(this.thumb)
this.switch.append(this.toggleBar)
this.appendChild(this.labelLeft)
this.appendChild(this.switch)
this.appendChild(this.labelRight)
this.setAttribute('tabindex', this.getBZAttribute('tabindex'))
this.switch.addEventListener('click', this.toggle.bind(this))
}
turnOn() {
if(this.getBZAttribute('classOff')) this.switch.classList.remove(this.getBZAttribute('classOff'))
if(this.getBZAttribute('classOn')) this.switch.classList.add(this.getBZAttribute('classOn'))
this.thumb.classList.add('turned-on')
this.value = this.getBZAttribute('trueValue')
this.focus()
}
turnOff() {
if(this.getBZAttribute('classOn')) this.switch.classList.remove(this.getBZAttribute('classOn'))
if(this.getBZAttribute('classOff'))this.switch.classList.add(this.getBZAttribute('classOff'))
this.thumb.classList.remove('turned-on')
this.value = this.getBZAttribute('falseValue')
this.focus()
}
toggle(event) {
if(event) { event.preventDefault(); event.stopPropagation(); }
if(this.getBZAttribute('disabled')) return
if(this.value == this.getBZAttribute('trueValue')) this.turnOff()
else this.turnOn()
this.dispatchEvent(new Event('change', {
bubbles: true,
composed: false,
cancelable: false
}))
}
}
Buildoz.define('toggler', BZtoggler)
+4 -1
View File
@@ -23,10 +23,13 @@
<article eiccard> <article eiccard>
<section> <section>
Arena Arena
<bz-toggler labelLeft="gauche" data-output="testToggler"></bz-toggler>
<bz-toggler labelRight="droite"></bz-toggler>
<bz-toggler labelLeft="gauche" labelRight="droite"></bz-toggler>
</section> </section>
</article> </article>
<article eiccard=""> <article eiccard="">
<header>Properties</header> <header><h1>Agent properties</h1></header>
<section>Props form</section> <section>Props form</section>
</article> </article>
+57 -6
View File
@@ -21,23 +21,74 @@ class KeyframeView extends WindozDomContent {
this.setupTriggers(components) this.setupTriggers(components)
this.setupRefs(components) this.setupRefs(components)
this.agentDefs = await this.models.agents.getSprites('Basic 3D') const [sprites, types] = await Promise.all([
this.outputs.agentsSelector.fillOptions( Object.keys(this.agentDefs).map(aname => { this.models.agents.getSprites('Basic 3D'),
console.log(this.agentDefs[aname]) this.models.agents.getTypes('Test agents')
return({ markup: `${aname}`, value: aname}) ])
this.agentSprites = sprites
this.agentTypes = types
this.outputs.agentsSelector.fillOptions( this.agentTypes.map(item => {
return({ markup: `${item.atp_name}`, value: item.atp_id})
})) }))
this.outputs.agentsSelector.addEventListener('change',this.onChangeAgent.bind(this)) this.outputs.agentsSelector.addEventListener('change',this.onChangeAgent.bind(this))
this.agentPreview = new app.LoadedModules.AgentPreview(this.outputs.agentSampleCanvas, this.agentDefs) this.agentPreview = new app.LoadedModules.AgentPreview(this.outputs.agentSampleCanvas, this.agentSprites)
this.onChangeAgent() this.onChangeAgent()
this.agentPreview.startRendering() this.agentPreview.startRendering()
this.agentPreview.animation = true this.agentPreview.animation = true
this.outputs.testToggler.addEventListener('change',(e)=> {
console.log(e.target.value, e)
})
} }
onChangeAgent(event){ async onChangeAgent(event){
if(this.outputs.agentsSelector.value) this.agentPreview.setAgent(this.outputs.agentsSelector.value) if(this.outputs.agentsSelector.value) this.agentPreview.setAgent(this.outputs.agentsSelector.value)
if(!this.outputs.agentsSelector.value) return
const agent = await this.models.agents.getProperties(this.outputs.agentsSelector.value)
this.fillAgentProperties(agent.atp_props)
}
fillAgentProperties(agentProps){
for(const propName in agentProps){
const fieldRow = ui.create(`<div class="cols-2"><label>${propName}</label></div>`)
let component
switch(agentProps[propName].type){
case 'number':
component = document.createElement('input')
component.setAttribute('type','number')
if(agentProps[propName].min) component.setAttribute('min', agentProps[propName].min)
if(agentProps[propName].max) component.setAttribute('max', agentProps[propName].max)
component.value = agentProps[propName].default
break
case 'string':
component = document.createElement('input')
component.setAttribute('type','text')
break
case 'boolean':
component = new InputToggler({
value: agentProps[propName].default,
})
fieldRow.append(component.el)
break
case 'list':
component = document.createElement('bz-select')
component.fillOptions( agentProps[propName].choices.map(item => {
return({ markup: `${item}`, value: item})
}))
break
default:
console.warn(`Unknown field type ${agentProps[propName].type}`)
}
fieldRow.append(component)
}
} }
} }
@@ -4,11 +4,11 @@ import * as TWEEN from '/app/thirdparty/Three/tween.module.js'
export class AgentPreview{ export class AgentPreview{
constructor(canvasEl, agentDefs){ constructor(canvasEl, agentSprites){
Object.assign(this, app.helpers.helpers3D) Object.assign(this, app.helpers.helpers3D)
this.agentDefs = app.Assets.Store.json.agentDefs this.agentSprites = app.Assets.Store.json.agentSprites
this.canvasEl = canvasEl this.canvasEl = canvasEl
this.agentDefs = agentDefs this.agentSprites = agentSprites
this.currentAgentObj = null this.currentAgentObj = null
this.renderer = null this.renderer = null
this._animation = false this._animation = false
@@ -41,11 +41,13 @@ export class AgentPreview{
this.renderer.render(this.scene, this.camera) this.renderer.render(this.scene, this.camera)
} }
setAgent(atype){ setAgent(id){
if(this.currentAgentObj && (this.scene.children.includes(this.currentAgentObj))){ if(this.currentAgentObj && (this.scene.children.includes(this.currentAgentObj))){
this.scene.remove(this.currentAgentObj) this.scene.remove(this.currentAgentObj)
} }
this.currentAgentObj = this.agentFromJSON('previewedAgent', this.agentDefs[atype]) const agentSprite = this.agentSprites.find(item => item.atp_id==id)
if(!agentSprite) return
this.currentAgentObj = this.agentFromJSON('previewedAgent', agentSprite.asp_3d)
this.currentAgentObj.position.set(0, 0, 0) this.currentAgentObj.position.set(0, 0, 0)
this.scene.add(this.currentAgentObj) this.scene.add(this.currentAgentObj)
+1 -1
View File
@@ -99,7 +99,7 @@ class MessageBusWorker {
} }
if((data.action=='PING') && this.keepAlive){ // Keep Alive is managed here if((data.action=='PING') && this.keepAlive){ // Keep Alive is managed here
this.clientActionDispatch({'action':'PONG'}); this.clientActionDispatch({'action':'PONG', 'reqid':data.reqid});
return return
} }