Deploy web Studio / deploy (push) Successful in 1m5s
Groups: objects of type "group" draw nothing; members carry the group's id in a new `group` field (groups nest). A hidden group hides everything in it (Doc::hidden_in_groups, skipped by the driver), a locked one locks it in the Studio. Removing a group moves its members up into its parent group. isokit check warns about members of missing groups. New `order` op: the whole object order at once (each id once), one undo step. Studio object list as a tree in the document order, front first: each group sits just after its members, so it draws as one block, and ground pieces higher in the list lie on top. Groups fold open and shut; every row has an eye and a lock (shown on hover or when set); a click on a group selects all of it, so a drag on the map moves it all. Group / Ungroup (Ctrl+G, Ctrl+Shift+G), Order up/down (Ctrl+] Ctrl+[, with Shift to the front / back), drag rows above, below or into a group. Group panel: name, zoom, ungroup, to front / back, lock, hide, delete with contents. MCP: group field in the object schema, order op, guidance. Tests: Rust 81 (ops: groups, order, removal; driver: nested hidden groups), Studio 131, web 100.
92 lines
6.0 KiB
HTML
92 lines
6.0 KiB
HTML
<!doctype html>
|
||
<html lang="en">
|
||
<head>
|
||
<meta charset="utf-8">
|
||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||
<title>isokit Studio</title>
|
||
<script>
|
||
(function(){var t=null;try{t=localStorage.getItem("isokit-theme")}catch(e){}
|
||
if(t!=="light"&&t!=="dark")t=window.matchMedia&&matchMedia("(prefers-color-scheme: light)").matches?"light":"dark";
|
||
document.documentElement.setAttribute("data-theme",t);})();
|
||
</script>
|
||
<link rel="icon" type="image/svg+xml" href="/assets/studio/favicon.svg">
|
||
<link rel="stylesheet" href="/assets/viewer/isokit-view.css">
|
||
<link rel="stylesheet" href="/assets/theme.css">
|
||
<link rel="stylesheet" href="/assets/studio/studio.css">
|
||
</head>
|
||
<body>
|
||
<header class="st-head">
|
||
<b class="st-logo">isokit <span>Studio</span></b>
|
||
<span class="st-title" id="title"></span>
|
||
<span class="st-grow"></span>
|
||
<button type="button" id="undo" title="Undo (Ctrl+Z)" disabled>↶ Undo</button>
|
||
<button type="button" id="redo" title="Redo (Ctrl+Y)" disabled>↷ Redo</button>
|
||
<span class="st-save" id="save" title="Every change is saved to scene.json at once">Saved</span>
|
||
<span class="st-sep"></span>
|
||
<a class="st-btn" id="preview" href="/view" target="_blank" rel="noopener" title="The scene as visitors see it (live)">Preview</a>
|
||
<button type="button" id="build" title="Write the self-contained HTML page">Build page</button>
|
||
<button type="button" id="theme" title="Light / dark">◐</button>
|
||
<button type="button" id="help" title="Keys and tips">?</button>
|
||
</header>
|
||
<main class="st-main">
|
||
<aside class="st-left">
|
||
<section class="st-panel st-pal-panel">
|
||
<h2>Add <small>click, then click or drag on the map</small></h2>
|
||
<input type="search" id="psearch" placeholder="Search objects…" autocomplete="off">
|
||
<div id="palette" class="st-palette"></div>
|
||
</section>
|
||
<section class="st-panel st-grow-panel">
|
||
<h2>Objects <small id="ocount"></small></h2>
|
||
<input type="search" id="osearch" placeholder="Filter…" autocomplete="off">
|
||
<div class="st-otools">
|
||
<button type="button" id="ogroup" title="Group the selected objects (Ctrl+G)">▤ Group</button>
|
||
<button type="button" id="oungroup" title="Ungroup (Ctrl+Shift+G)">Ungroup</button>
|
||
<span title="The order draws ground pieces (areas, beds, ponds, roads): higher in the list lies on top. Drag rows to reorder, or into a group">Order</span>
|
||
<button type="button" id="ofwd" title="Forward: draw on top of the one above (Ctrl+]); Shift: to the front (Ctrl+Shift+])">▲</button>
|
||
<button type="button" id="obwd" title="Backward (Ctrl+[); Shift: to the back (Ctrl+Shift+[)">▼</button>
|
||
</div>
|
||
<ul id="objects" class="st-objects"></ul>
|
||
</section>
|
||
</aside>
|
||
<section class="st-centre">
|
||
<div id="view" class="iso-fill"></div>
|
||
<div class="st-hint" id="hint" hidden></div>
|
||
<footer class="st-status">
|
||
<span id="cursor">x – y –</span>
|
||
<label title="Snap positions to a grid">Snap
|
||
<select id="snap"><option value="0">off</option><option value="0.1">0.1 m</option><option value="0.5" selected>0.5 m</option><option value="1">1 m</option><option value="5">5 m</option></select>
|
||
</label>
|
||
<span class="st-grow"></span>
|
||
<button type="button" id="warnbtn" class="st-link" hidden></button>
|
||
<span id="stats"></span>
|
||
<a id="ver" class="st-ver" href="https://git.b4l.co.th/B4L/isokit" target="_blank" rel="noopener"></a>
|
||
</footer>
|
||
</section>
|
||
<aside class="st-right" id="right"></aside>
|
||
</main>
|
||
<div class="st-toast" id="toast" hidden></div>
|
||
<dialog id="helpdlg" class="st-dialog">
|
||
<h3>isokit Studio</h3>
|
||
<table>
|
||
<tr><th>Add</th><td>pick an object on the left, click on the map (Shift-click to place several)</td></tr>
|
||
<tr><th>Draw</th><td>walls, fences, hedges, roads: drag along the map for one piece, or click corner after corner for a run (double-click or Enter ends it, clicking the first corner closes it, Backspace drops the last corner); ends snap onto the walls and fences they meet, which then join at corners and T-junctions. Floors, areas, buildings, roofs: drag a rectangle; Room: drag a rectangle for a floor with walls around it</td></tr>
|
||
<tr><th>Windows, doors</th><td>click on a wall: they snap onto it, cut their opening and move, turn, copy and delete with the wall; R turns a door to the other hinge and swing side</td></tr>
|
||
<tr><th>Storeys</th><td>GF, 1F, … cut a house open; on 1F and up, new walls, floors and furniture go onto that storey (3 m each, parameter <code>storey_h</code>)</td></tr>
|
||
<tr><th>Select</th><td>click it on the map or in the list; click a wall or fence again to select every piece joined to it (again: just that one)</td></tr>
|
||
<tr><th>Several</th><td>Ctrl+click (map or list) adds or takes out one, Shift+click in the list selects a range, Shift+drag on the map selects what lies inside the box, Ctrl+A everything not locked, Esc none. Drag one of them, arrow keys, R, Ctrl+D and Delete then work on all; the form edits a property for all of them</td></tr>
|
||
<tr><th>Move</th><td>drag it, or arrow keys (by the snap step)</td></tr>
|
||
<tr><th>Turn</th><td>R / Shift+R, or the ⟲ ⟳ buttons</td></tr>
|
||
<tr><th>Copy / delete</th><td>Ctrl+D / Delete</td></tr>
|
||
<tr><th>Undo / redo</th><td>Ctrl+Z / Ctrl+Y</td></tr>
|
||
<tr><th>View</th><td>drag the ground to pan, or drag with the middle mouse button anywhere (it never moves an object); Ctrl + wheel or pinch to zoom, ↺ ↻ to rotate, levels to look inside</td></tr>
|
||
<tr><th>Agent</th><td>✦ Agent opens a chat with a language model that edits the scene for you; Undo takes its steps back. Drag the window by its title, resize it at the top-left corner</td></tr>
|
||
<tr><th>MCP</th><td>connect an AI agent over MCP; its edits appear here live (see the panel when nothing is selected)</td></tr>
|
||
</table>
|
||
<form method="dialog"><button>Close</button></form>
|
||
</dialog>
|
||
<script src="/assets/viewer/isokit-view.js"></script>
|
||
<script src="/assets/studio/studio.js"></script>
|
||
<script src="/assets/studio/agent.js"></script>
|
||
</body>
|
||
</html>
|