import { pickAssetType } from './lib/scaffold.mjs'; /** Text assets rendered in the scene, and the enabled switch in the editor and in the running game. */ export async function textAndEnabled(t) { const { check, evaluate, json, has, shot, click, clickText, locate, mutate, object, play, press, stop, typeText, } = t; // 10a. Text assets: created through the + menu, placed, and rendered as real text in the scene. await clickText('+'); await pickAssetType(t, 'Text'); const textAssetId = await evaluate(`(__gm.state.project.assets.find(a => a.type === 'text') || {}).id`); check('+ menu creates a text asset', Boolean(textAssetId)); await mutate(` const id = ${JSON.stringify(textAssetId)}; __gm.state.project.assets.find(a => a.id === id).props.text = 'Hello world'; // On the camera so the game view really renders it (outside the frame it would be culled). const cam = __gm.state.activeScene.objects.find(o => o.id === 'o3').position; __gm.state.activeScene.objects.push({ id: 'otext', assetId: id, name: '', position: { x: cam.x, y: cam.y, z: 5 }, editorOffset: { x: 0, y: 0 }, overrides: {}, parentId: '', instanceEdits: {} }); __gm.state.select({ kind: 'object', holderId: 'scene1', objectIds: ['otext'], objectId: 'otext' })`); check('a placed text object draws its content in the scene', await has('Hello world')); await shot('29-text-object'); // 10b. The enabled switch: every object has it, switching it off is a normal override, and a // switched-off object disappears from the scene view too (it stays in the hierarchy). const enabledRow = await json("__gm.inspectorField('Enabled')"); check('the inspector shows the Enabled switch for a scene object', Boolean(enabledRow)); const visibleBefore = (await json('__gm.viewportInfo()')).visibleItems; const gizmoOf = async (id) => (await json('__gm.gizmos()')).find((g) => g.id === id) ?? null; const gizmoOn = await gizmoOf('otext'); check('a selected object is framed at full strength', gizmoOn?.alpha === 1, JSON.stringify(gizmoOn)); await click(enabledRow.x, enabledRow.y); const textObject = await object('otext'); check( 'clicking it writes an override instead of changing the asset', textObject.overrides.enabled === false, JSON.stringify(textObject.overrides), ); check( 'a switched-off object is not drawn in the scene view', !(await json('__gm.drawOrder()')).includes('otext'), ); const visibleAfter = (await json('__gm.viewportInfo()')).visibleItems; check( 'the scene view renders one item less', visibleAfter === visibleBefore - 1, `${visibleBefore} → ${visibleAfter}`, ); check('it stays selectable in the hierarchy, so its switch stays reachable', await has('Enabled')); await shot('30-disabled'); // 17a-2. It draws nothing, so its outline is the only thing left that says where it sits – which // is the whole point of being able to pick it in the hierarchy. Selecting another object // and coming back proves the outline follows the panel, not a leftover from before. const gizmoOff = await gizmoOf('otext'); check( 'a switched-off object is still framed, dimmed', gizmoOff?.primary === true && gizmoOff.alpha > 0 && gizmoOff.alpha < 1, JSON.stringify(gizmoOff), ); const otherRow = await evaluate(`__gm.hierarchyRow('o3')`); await click(otherRow.x, otherRow.y); check('selecting something else drops the frame', (await gizmoOf('otext')) === null); const offRow = await evaluate(`__gm.hierarchyRow('otext')`); await click(offRow.x, offRow.y); const gizmoBack = await gizmoOf('otext'); check( 'picking the switched-off object in the hierarchy frames it again', gizmoBack?.alpha > 0 && gizmoBack.alpha < 1, JSON.stringify(gizmoBack), ); check('and it is still not drawn', !(await json('__gm.drawOrder()')).includes('otext')); await shot('30b-disabled-gizmo'); // 10c. In the running game a switched-off object does not exist: it is not rendered, and // switching it back on brings it back. await play(); const offItems = (await json('__gm.gameInfo()')).visibleItems; await mutate(`__gm.state.activeScene.objects.find(o => o.id === 'otext').overrides.enabled = true`); const onItems = (await json('__gm.gameInfo()')).visibleItems; check( 'the game renders one item more once the object is switched on', onItems === offItems + 1, `${offItems} → ${onItems}`, ); await stop(); check('stop leaves the play-mode switch behind', (await object('otext')).overrides.enabled === false); // 10d. A field that shows no decimals must not store any either. Font size is such a field, so // typing a fraction has to round: showing "33" while the project holds 32.6 would be a lie. const fontLabel = await locate('Font size'); check('Font size reads as a whole number', Boolean(await has('32')) && !(await has('32.000'))); await click(fontLabel.x + 160, fontLabel.y); await typeText('32.6'); await press('Enter'); const fontSize = (await object('otext')).overrides.fontSize; check('typing a fraction into it rounds the stored value', fontSize === 33, String(fontSize)); check('and the field shows exactly what was stored', Boolean(await has('33'))); }