iobroker.mywebui 1.42.4 → 1.42.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json
CHANGED
|
@@ -27,10 +27,6 @@ export class IobrokerWebui3DScreenEditor extends BaseCustomWebComponentConstruct
|
|
|
27
27
|
</div>
|
|
28
28
|
</div>
|
|
29
29
|
<div id="viewport" style="flex:1;background:#333;position:relative;overflow:hidden;"></div>
|
|
30
|
-
<div id="rightPanel" style="width:300px;background:#1e1e1e;border-left:1px solid #444;overflow:auto;">
|
|
31
|
-
<div style="padding:10px;font-weight:bold;color:#aaa;border-bottom:1px solid #444;">Properties</div>
|
|
32
|
-
<div id="propertyPanel" style="padding:10px;"></div>
|
|
33
|
-
</div>
|
|
34
30
|
</div>
|
|
35
31
|
</div>
|
|
36
32
|
`;
|
|
@@ -219,16 +215,20 @@ export class IobrokerWebui3DScreenEditor extends BaseCustomWebComponentConstruct
|
|
|
219
215
|
updateSceneView() {
|
|
220
216
|
if (!this.sceneData) return;
|
|
221
217
|
|
|
222
|
-
// Add assets to scene
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
218
|
+
// Add assets to scene (safe iteration)
|
|
219
|
+
if (Array.isArray(this.sceneData.assets)) {
|
|
220
|
+
for (const asset of this.sceneData.assets) {
|
|
221
|
+
if (asset.type === 'model' && asset.glbPath) {
|
|
222
|
+
this.loadAsset(asset);
|
|
223
|
+
}
|
|
226
224
|
}
|
|
227
225
|
}
|
|
228
226
|
|
|
229
|
-
// Update lights
|
|
230
|
-
|
|
231
|
-
this.
|
|
227
|
+
// Update lights (safe iteration)
|
|
228
|
+
if (Array.isArray(this.sceneData.lights)) {
|
|
229
|
+
for (const light of this.sceneData.lights) {
|
|
230
|
+
this.addLightToScene(light);
|
|
231
|
+
}
|
|
232
232
|
}
|
|
233
233
|
|
|
234
234
|
// Update camera
|
|
@@ -242,9 +242,6 @@ export class IobrokerWebui3DScreenEditor extends BaseCustomWebComponentConstruct
|
|
|
242
242
|
|
|
243
243
|
// Update scene tree
|
|
244
244
|
this.updateSceneTree();
|
|
245
|
-
|
|
246
|
-
// Update property panel
|
|
247
|
-
this.updatePropertyPanel();
|
|
248
245
|
}
|
|
249
246
|
|
|
250
247
|
loadAsset(asset) {
|
|
@@ -316,9 +313,18 @@ export class IobrokerWebui3DScreenEditor extends BaseCustomWebComponentConstruct
|
|
|
316
313
|
|
|
317
314
|
for (const intersection of intersects) {
|
|
318
315
|
const obj = intersection.object;
|
|
319
|
-
if (obj.userData.
|
|
316
|
+
if (obj.userData.assetData) {
|
|
320
317
|
this.selectObject(obj);
|
|
321
|
-
|
|
318
|
+
return;
|
|
319
|
+
}
|
|
320
|
+
// Try parent objects
|
|
321
|
+
let parent = obj.parent;
|
|
322
|
+
while (parent && parent !== this.scene) {
|
|
323
|
+
if (parent.userData.assetData) {
|
|
324
|
+
this.selectObject(parent);
|
|
325
|
+
return;
|
|
326
|
+
}
|
|
327
|
+
parent = parent.parent;
|
|
322
328
|
}
|
|
323
329
|
}
|
|
324
330
|
}
|
|
@@ -326,16 +332,37 @@ export class IobrokerWebui3DScreenEditor extends BaseCustomWebComponentConstruct
|
|
|
326
332
|
selectObject(obj) {
|
|
327
333
|
if (this.selectedObject === obj) return;
|
|
328
334
|
|
|
329
|
-
// Deselect previous
|
|
335
|
+
// Deselect previous (remove highlight)
|
|
330
336
|
if (this.selectedObject) {
|
|
331
337
|
this.selectedObject.userData.selected = false;
|
|
338
|
+
// Restore original material
|
|
339
|
+
this.selectedObject.traverse((child) => {
|
|
340
|
+
if (child.material && child.userData.originalMaterial) {
|
|
341
|
+
child.material = child.userData.originalMaterial;
|
|
342
|
+
}
|
|
343
|
+
});
|
|
332
344
|
}
|
|
333
345
|
|
|
334
|
-
// Select new
|
|
346
|
+
// Select new (add yellow highlight)
|
|
335
347
|
this.selectedObject = obj;
|
|
336
348
|
obj.userData.selected = true;
|
|
337
349
|
|
|
338
|
-
|
|
350
|
+
// Apply highlight material
|
|
351
|
+
obj.traverse((child) => {
|
|
352
|
+
if (child.material) {
|
|
353
|
+
child.userData.originalMaterial = child.material;
|
|
354
|
+
const hlMat = new this.THREE.MeshStandardMaterial({
|
|
355
|
+
color: 0xffff00,
|
|
356
|
+
emissive: 0xffff00,
|
|
357
|
+
emissiveIntensity: 0.3,
|
|
358
|
+
metalness: 0.3,
|
|
359
|
+
roughness: 0.4
|
|
360
|
+
});
|
|
361
|
+
child.material = hlMat;
|
|
362
|
+
}
|
|
363
|
+
});
|
|
364
|
+
|
|
365
|
+
console.log('✅ Selected:', obj.userData.assetData.name);
|
|
339
366
|
}
|
|
340
367
|
|
|
341
368
|
updateSceneTree() {
|
|
@@ -343,7 +370,7 @@ export class IobrokerWebui3DScreenEditor extends BaseCustomWebComponentConstruct
|
|
|
343
370
|
treeEl.innerHTML = '';
|
|
344
371
|
|
|
345
372
|
// Assets
|
|
346
|
-
if (this.sceneData.assets && this.sceneData.assets.length > 0) {
|
|
373
|
+
if (Array.isArray(this.sceneData.assets) && this.sceneData.assets.length > 0) {
|
|
347
374
|
const assetsDiv = document.createElement('div');
|
|
348
375
|
assetsDiv.style.cssText = 'margin-bottom:10px;';
|
|
349
376
|
|
|
@@ -355,8 +382,10 @@ export class IobrokerWebui3DScreenEditor extends BaseCustomWebComponentConstruct
|
|
|
355
382
|
for (const asset of this.sceneData.assets) {
|
|
356
383
|
const itemDiv = document.createElement('div');
|
|
357
384
|
itemDiv.textContent = asset.name;
|
|
358
|
-
itemDiv.style.cssText = 'padding:5px;cursor:pointer;color:#aaa;margin-left:10px;';
|
|
359
|
-
itemDiv.addEventListener('click', () =>
|
|
385
|
+
itemDiv.style.cssText = 'padding:5px;cursor:pointer;color:#aaa;margin-left:10px;background:#2a2a1a;border-radius:3px;margin-bottom:3px;';
|
|
386
|
+
itemDiv.addEventListener('click', () => {
|
|
387
|
+
this.selectAssetByName(asset.name);
|
|
388
|
+
});
|
|
360
389
|
assetsDiv.appendChild(itemDiv);
|
|
361
390
|
}
|
|
362
391
|
|
|
@@ -364,7 +393,7 @@ export class IobrokerWebui3DScreenEditor extends BaseCustomWebComponentConstruct
|
|
|
364
393
|
}
|
|
365
394
|
|
|
366
395
|
// Lights
|
|
367
|
-
if (this.sceneData.lights && this.sceneData.lights.length > 0) {
|
|
396
|
+
if (Array.isArray(this.sceneData.lights) && this.sceneData.lights.length > 0) {
|
|
368
397
|
const lightsDiv = document.createElement('div');
|
|
369
398
|
lightsDiv.style.cssText = 'margin-bottom:10px;';
|
|
370
399
|
|
|
@@ -394,6 +423,16 @@ export class IobrokerWebui3DScreenEditor extends BaseCustomWebComponentConstruct
|
|
|
394
423
|
}
|
|
395
424
|
}
|
|
396
425
|
|
|
426
|
+
selectAssetByName(assetName) {
|
|
427
|
+
// Find and select asset in scene tree
|
|
428
|
+
for (const obj of this.scene.children) {
|
|
429
|
+
if (obj.userData.assetData && obj.userData.assetData.name === assetName) {
|
|
430
|
+
this.selectObject(obj);
|
|
431
|
+
break;
|
|
432
|
+
}
|
|
433
|
+
}
|
|
434
|
+
}
|
|
435
|
+
|
|
397
436
|
updatePropertyPanel() {
|
|
398
437
|
const panelEl = this._getDomElement('propertyPanel');
|
|
399
438
|
panelEl.innerHTML = '';
|
|
@@ -119,8 +119,69 @@ export class IobrokerWebuiSolutionExplorer extends BaseCustomWebComponentConstru
|
|
|
119
119
|
try {
|
|
120
120
|
let screenName = prompt("New " + type + " Name:");
|
|
121
121
|
if (screenName) {
|
|
122
|
-
|
|
123
|
-
|
|
122
|
+
if (type === '3dscreen') {
|
|
123
|
+
// Create new 3D screen with default scene
|
|
124
|
+
const defaultScene = {
|
|
125
|
+
id: 'scene_' + Date.now().toString(36),
|
|
126
|
+
name: screenName,
|
|
127
|
+
version: '1.0',
|
|
128
|
+
createdAt: new Date().toISOString(),
|
|
129
|
+
modifiedAt: new Date().toISOString(),
|
|
130
|
+
assets: [],
|
|
131
|
+
lights: [
|
|
132
|
+
{
|
|
133
|
+
id: 'ambient_light',
|
|
134
|
+
name: 'Ambient Light',
|
|
135
|
+
type: 'ambient',
|
|
136
|
+
color: '#ffffff',
|
|
137
|
+
intensity: 0.6
|
|
138
|
+
},
|
|
139
|
+
{
|
|
140
|
+
id: 'directional_light',
|
|
141
|
+
name: 'Directional Light',
|
|
142
|
+
type: 'directional',
|
|
143
|
+
color: '#ffffff',
|
|
144
|
+
intensity: 0.8,
|
|
145
|
+
position: { x: 10, y: 10, z: 10 },
|
|
146
|
+
castShadow: true
|
|
147
|
+
}
|
|
148
|
+
],
|
|
149
|
+
camera: {
|
|
150
|
+
position: { x: 10, y: 10, z: 10 },
|
|
151
|
+
target: { x: 0, y: 0, z: 0 },
|
|
152
|
+
fov: 75
|
|
153
|
+
},
|
|
154
|
+
grid: {
|
|
155
|
+
visible: true,
|
|
156
|
+
size: 20,
|
|
157
|
+
divisions: 20,
|
|
158
|
+
colorCenterLine: '#888888',
|
|
159
|
+
colorGrid: '#444444'
|
|
160
|
+
},
|
|
161
|
+
axes: {
|
|
162
|
+
visible: true,
|
|
163
|
+
size: 5
|
|
164
|
+
},
|
|
165
|
+
settings: {
|
|
166
|
+
backgroundColor: '#333333',
|
|
167
|
+
enableControls: true,
|
|
168
|
+
enableRaycasting: true,
|
|
169
|
+
shadowsEnabled: true,
|
|
170
|
+
antialiasing: true
|
|
171
|
+
},
|
|
172
|
+
edits: {
|
|
173
|
+
ops: []
|
|
174
|
+
}
|
|
175
|
+
};
|
|
176
|
+
await iobrokerHandler.saveObject('3dscreen', (dir ?? '') + '/' + screenName, defaultScene);
|
|
177
|
+
// Open the 3D editor
|
|
178
|
+
const editor = document.createElement('iobroker-webui-3dscreen-editor');
|
|
179
|
+
editor.setAttribute('scene-name', screenName);
|
|
180
|
+
window.appShell.openDialog(editor, { x: 50, y: 50, width: 1200, height: 800 });
|
|
181
|
+
} else {
|
|
182
|
+
const defaultScript = type === 'control' ? defaultNewControlScript : null;
|
|
183
|
+
window.appShell.openScreenEditor((dir ?? '') + '/' + screenName, type, '', defaultNewStyle, defaultScript, {});
|
|
184
|
+
}
|
|
124
185
|
}
|
|
125
186
|
}
|
|
126
187
|
catch (err) {
|