diff --git a/README.md b/README.md index e1761df..b273e8e 100644 --- a/README.md +++ b/README.md @@ -13,7 +13,7 @@ headset runs, and lets you edit, save and send them to the headset. 2. **Prepare the headset** once: developer mode, SSH and a key. See [Preparing the Steam Frame](docs/headset-setup.md). 3. **Install Frame Home**: in Studio, **Headset > Install on Steam Frame...**, then **Install Frame Home**. See [Installing Frame Home](docs/install-frame-home.md). -4. **Open a home**: **File > Open Home...** and pick a Meta home `.apk`, a `.fenv` or a model. +4. **Open a home**: **File > Open...** and pick a Meta home `.apk`, a `.fenv` or a model. 5. **Send it**: **Headset > Send to Frame**. Put the headset on: you are standing in it. ## Downloads @@ -106,7 +106,8 @@ Frame Studio and Frame Home are licensed under the **GNU Affero General Public L You may use, study, change and share them; if you share a changed version, or run one for others over a network, its source must be available under the same license. -Vendored libraries in `third_party/` keep their own licenses (in each folder). The home loaders in `third_party/qhe` +Vendored libraries in `third_party/` keep their own licenses (in each folder); Studio's interface font, Inter, is under +the SIL Open Font License (`third_party/inter/LICENSE.txt`). The home loaders in `third_party/qhe` started from Quest Home Editor and keep its MIT license for the original code; see [third_party/qhe/LICENSE.md](third_party/qhe/LICENSE.md). diff --git a/docs/bundles.md b/docs/bundles.md index 070a228..8680c1c 100644 --- a/docs/bundles.md +++ b/docs/bundles.md @@ -6,9 +6,9 @@ files it holds, and the Environments panel lists each one separately. ## Making a bundle in Frame Studio -Everything is in the **Bundle** menu and on the Inspector's **Bundle** tab. +Everything is in **File > Bundle** and on the **Bundle** tab in Properties. -1. **Bundle > New Bundle** starts an empty one, and the **Bundle** tab opens. +1. **File > Bundle > New Bundle** starts an empty one, and the **Bundle** tab opens. 2. Give it a **Name**. It's the bundle's own name; each environment keeps its name. 3. Add environments: - **Add the Open Environment**: the environment you have open, as it was last saved. Save first (Ctrl+S) to @@ -24,7 +24,7 @@ Everything is in the **Bundle** menu and on the Inspector's **Bundle** tab. ## Opening a bundle -**Bundle > Open Bundle...**, **File > Open Home...**, or dropping a `.fbundle` on the window opens the bundle on the +**File > Bundle > Open Bundle...**, **File > Open...**, or dropping a `.fbundle` on the window opens the bundle on the Bundle tab. Its environments are listed in place; nothing is unpacked yet. - Double-click an environment to open it. It is unpacked into a scratch folder first. diff --git a/docs/environments-and-fenv.md b/docs/environments-and-fenv.md index 213e079..d9404cd 100644 --- a/docs/environments-and-fenv.md +++ b/docs/environments-and-fenv.md @@ -49,7 +49,7 @@ A home with a room and its vista is usually larger than either alone. ## Making a .fenv in Frame Studio -1. Open a home: **File > Open Home...**. +1. Open a home: **File > Open...**. 2. Edit it if you like. 3. **File > Save to My Environments** (Ctrl+S) or **File > Save As...**. @@ -129,7 +129,7 @@ Prints the name, baked or wrapped, its sources and models, whether it has edits ``` Lists what the home is made of, what it costs, and problems found. It ends with exit code 3 when the home is broken. -Studio shows the same under **Debug > Home Report...**. +Studio shows the same under **Window > Home Report...**. ## Per-world settings diff --git a/docs/getting-started.md b/docs/getting-started.md index 109ab65..b325c0c 100644 --- a/docs/getting-started.md +++ b/docs/getting-started.md @@ -115,10 +115,10 @@ Before you start, set up the headset once: [headset-setup.md](headset-setup.md). ### 1. Open a home -1. Choose **File > Open Home...** (Ctrl+O), or drop files onto the Studio window. +1. Choose **File > Open...** (Ctrl+O), or drop files onto the Studio window. 2. Pick a Meta home (`.apk`), a `.fenv` environment, or a model. - To open a room together with its view outside (a "footprint" and a "vista"), select both files in the dialog. - You can also add a vista later with **File > Add Vista...**. + You can also add a vista later with **File > Import > Vista...**. 3. Wait for the home to load. Studio shows its progress. ### 2. Look around @@ -134,8 +134,9 @@ Before you start, set up the headset once: [headset-setup.md](headset-setup.md). **Help > Controls** (F1) lists every shortcut. -To change something, select an object, then use **Edit > Move** (G), **Rotate** (R), **Scale** (S), **Hide -Selected** (H) or **Delete Selected** (X). The selected object's details show in the Inspector on the right. +To change something, select an object, then pick **Move** (G), **Rotate** (R) or **Scale** (S) in the toolbar on the +left of the view and drag the gizmo, or use **Object > Show/Hide** (H) or **Object > Delete** (X). The selected +object's details show in Properties, on the right. Shift+A adds things where you look; F3 finds any command. **Edit > Undo** (Ctrl+Z) takes any step back. ### 3. Save diff --git a/docs/install-frame-home.md b/docs/install-frame-home.md index 7c44747..d8d0144 100644 --- a/docs/install-frame-home.md +++ b/docs/install-frame-home.md @@ -8,7 +8,7 @@ Before you start, the headset needs developer mode and SSH: see [headset-setup.m ## Way 1: from Frame Studio -1. Open the Inspector's **Headset** tab (on the right), or choose **Headset > Install on Steam Frame...**, which opens it. +1. Open the **Headset** tab in Properties (on the right), or choose **Headset > Install on Steam Frame...**, which opens it. 2. In **Headset**, type the headset's address: an SSH alias such as `frame`, or `steamos@
`, for example `steamos@192.168.1.50`. Studio remembers it. 3. Under **Environments to install**, choose what to copy along: diff --git a/docs/performance.md b/docs/performance.md index c747a94..60496f2 100644 --- a/docs/performance.md +++ b/docs/performance.md @@ -27,7 +27,7 @@ lower Resolution"**, frames are late. The **Debug** page helps find what is slow: -- **View > GPU cost** tints each mesh: green is cheap, red is costly. +- The 3D Viewport's shading menu (▾ at the right of its header) **> GPU Cost** tints each mesh: green is cheap, red is costly. - **Costliest meshes** lists the most expensive ones. - **Leave out** See-through surfaces, Cut-out surfaces or Sky shows whether those are what's slow. @@ -35,11 +35,11 @@ See [using-frame-home.md](using-frame-home.md#the-debug-page). ### From your computer -- In Studio, **Edit > Settings...** shows "Now on the headset: ..." under the Steam Frame settings, read from the +- In Studio, **Edit > Preferences...** shows "Now on the headset: ..." under the Steam Frame settings, read from the headset. **Read from Headset** refreshes it. -- **Debug > Headset Debug...** shows and changes the headset's Debug page. -- **Debug > Home Report...** lists what the open home costs and what's wrong with it. -- Studio's own **Debug** views (Normal, Wireframe, Meshes, GPU Cost, Overdraw) and **Debug > Leave Out** work like the +- **Headset > Headset Debug...** shows and changes the headset's Debug page. +- **Window > Home Report...** lists what the open home costs and what's wrong with it. +- Studio's viewport shading (Material, Wireframe, Solid, GPU Cost, Overdraw, and **Leave Out** in its ▾ menu) works like the headset's, but they measure your computer's GPU, not the headset's. On the headset, Frame Home writes its numbers to `~/frame-home/stats.json` every 2 seconds (GPU and CPU time per @@ -90,7 +90,7 @@ Studio tries not to use your computer more than it needs to: - It draws at your display's refresh rate while its window has focus, and at 30 fps when it doesn't. - When nothing changes (no input for a second and nothing moving by itself), it stops drawing and waits for input. Playing animations, loading and saving keep it drawing. -- **Edit > Settings...** under "This PC (Frame Studio)" has Viewport resolution, Anti-aliasing, Texture limit and +- **Edit > Preferences...** under "This PC (Frame Studio)" has Viewport resolution, Anti-aliasing, Texture limit and Texture filtering for big homes on slower computers. Two environment variables help when measuring: diff --git a/docs/studio-guide.md b/docs/studio-guide.md index 4d94a15..a125e02 100644 --- a/docs/studio-guide.md +++ b/docs/studio-guide.md @@ -7,44 +7,54 @@ the headset. This guide walks through the window and the everyday tasks. To inst ## The window +Frame Studio is laid out the way Blender works: the window is split into **areas**, each showing one editor, with +a header along its top. + ``` -┌───────────────────────────────────────────────────────────────────────────┐ -│ File Edit View World Bundle Headset Debug Help menu bar │ -├────┬──────────────┬──────────────────────────────┬────────────────────────┤ -│ ✥ │ EXPLORER │ │ Selected World Env… … │ -│ ⟳ │ Filter… │ │ ───────────────────── │ -│ ⤢ │ ▾ Root │ 3D VIEW │ INSPECTOR │ -│ ✎ │ ▾ folder │ │ (the chosen tab's │ -│ ── │ object │ │ settings) │ -│ ◍ │ ▾ World │ │ │ -│ ☺ │ Spawns … │ │ │ -│ ⌗ │ │ │ │ -├────┴──────────────┴──────────────────────────────┴────────────────────────┤ -│ ❚❚ Pause ───────────●───────────────── 12.0 / 60.0 s Sound on │ -│ Home name · format · selection · fps Frame: sent … │ -└───────────────────────────────────────────────────────────────────────────┘ +┌────────────────────────────────────────────────────────────────────────────┐ +│ ◎ File Edit Headset Window Help │ Layout Walking Headset │ home name │ top bar +├──────────────────────────────────────────────────────┬─────────────────────┤ +│ ▣▾ Arrange▾ View Select Add Object Global▾ ◈ ◯◯◯▾ │ ☰▾ As in the File▾ 🔍 │ +│ ┌──┐ ● home › selection (axes) │ ▾ Root │ +│ │✥ │ 🔍 │ ▾ folder 👁 │ +│ │⟳ │ 3D VIEWPORT ✋ │ object 👁 │ Outliner +│ │⤢ │ 👤 ├─────────────────────┤ +│ │✎ │ ⤢ │ 🔧▾ Object │ +│ └──┘ │ ■ │ ▾ Object │ +│ (toolbar: T) (sidebar: N) ▸ │ 👣│ Location … │ Properties +├──────────────────────────────────────────────────────┤ ▣ │ ▾ Surface │ +│ 🕐▾ Playback▾ ⏮ ▶ ⏭ 12.0 / 60.0 s 🔊 │ ▤ │ … │ +│ 0 5 10 ▮12.0 15 20 25 30 … │ ⌂ │ │ Timeline +├──────────────────────────────────────────────────────┴─────────────────────┤ +│ 🖱 Select 🖱 Rotate View 🖱 Context Menu / Fly 182 objects | 60 fps │ status bar +└────────────────────────────────────────────────────────────────────────────┘ ``` -| Part | Where | What it's for | -|---|---|---| -| **Tool strip** | left edge | the transform tools, Draw Floor, and how the gizmo and the camera behave | -| **Explorer** | left | everything in the home: its objects (in the file's own folders, or grouped by kind) and its world items | -| **3D view** | middle | the home as the headset draws it, with the gizmo and the walkable area on top | -| **Inspector** | right | settings, in tabs: **Selected**, **World**, **Environment**, **Bundle**, **Headset** | -| **Timeline** | bottom | plays the home's animations and sound; drag to scrub through the loop | -| **Status bar** | very bottom | the home's name and format, what's selected, the frame rate, and whether the headset has it | +| Area | What it's for | +|---|---| +| **3D Viewport** | the home as the headset draws it. Its header has the mode (Arrange or Draw Floor), the **View**, **Select**, **Add** and **Object** menus, the gizmo's orientation (Global or Local), the world layer and the shading (Wireframe, Solid, Material, more in ▾). Inside it: the toolbar (T), the axes and navigation buttons, and the sidebar (N) | +| **Outliner** | everything in the home: its objects (as the file lays them out, or by kind) and its world items, with an eye to hide each | +| **Properties** | settings, in tabs down its left edge: **Object** (what you selected), **World** (where you can walk), **Environment** (name, picture, sound, headset settings), **Bundle**, **Headset** | +| **Timeline** | plays the home's animations and sound; click or drag in it to scrub through the loop | -Drag the thin lines between the Explorer, the 3D view and the Inspector to make any of them wider. +**Rearranging areas.** Drag the gutter between two areas to resize them. To move an area, drag the **editor button** +at the left of its header (the icon with ▾) and drop it on another area: onto its middle to stack them as tabs, or +onto an edge to split that area. Click the editor button to show a different editor in that area. **Window > Reset +Layout** puts everything back; **Ctrl+Space** fills the window with the 3D Viewport until you press it again. + +**Workspaces.** The tabs in the top bar switch between layouts made for a job: **Layout** (everything), **Walking** +(a big view with Properties on the World tab) and **Headset** (Properties on the Headset tab). Studio remembers +your layout between runs. ## Opening a home -- **File > Open Home...** (Ctrl+O), or drop a file on the window. It opens: +- **File > Open...** (Ctrl+O), or drop a file on the window. It opens: - a Meta home (`.apk`). A *footprint* (the room) and its *vista* (the world outside) are opened together: pick both in the file dialog, or open the footprint and Studio offers the vistas beside it; - a Frame environment (`.fenv`); - models from Blender or Unity (`.glb`, `.gltf`, `.fbx`, `.obj`). - **File > My Environments** lists what you have saved; **File > Open Recent** lists what you had open. -- **File > Add Vista...** gives a footprint its vista; **File > Add Models...** places models into the home. +- **File > Import > Vista...** gives a footprint its vista; **File > Import > Models...** places models into the home. - A big home asks after a while whether to keep waiting; **Stop Loading** cancels. ## Moving around in the 3D view @@ -55,22 +65,22 @@ Drag the thin lines between the Explorer, the 3D view and the Inspector to make | Pan | Shift + middle-drag | | Zoom | mouse wheel, or Ctrl + middle-drag | | Fly | hold the right mouse button + W A S D, Q / E down / up (wheel: speed, Shift: 4x) | -| Look from where you'd stand | **Player view** in the tool strip, P, or Numpad 0 | -| Frame the selection / everything | F / Home (or double-click a row in the Explorer) | +| Look from where you'd stand | the person button under the axes, P, or Numpad 0 | +| Frame the selection / everything | F or Numpad . / Home (or double-click a row in the Outliner) | Press **F1** (Help > Controls) for the full list. ## Selecting and editing objects -1. Click an object in the 3D view or the Explorer. The Inspector switches to **Selected**. -2. Pick a tool in the tool strip (or press its key) and drag the gizmo: +1. Click an object in the 3D view or the Outliner. Properties switches to its **Object** tab. +2. Pick a tool in the toolbar on the left of the view (or press its key) and drag the gizmo: - **Move** (G), **Rotate** (R), **Scale** (S). Hold Ctrl to snap. - - The globe / cube button switches the gizmo between the world's axes and the object's own. -3. Or type exact values in **Location**, **Rotation** and **Scale** in the Selected tab. + - **Global** / **Local** in the header switches the gizmo between the world's axes and the object's own. +3. Or type exact values in **Location**, **Rotation** and **Scale** in the Object tab. 4. In the same tab: **Visible**, **Reset** (back to where the home had it), **Only This** (hide everything else, I), and **Delete** (X). -The Explorer's eye buttons hide objects or whole folders. **Edit > Unhide All** (Alt+H) brings them back. Every +The Outliner's eye buttons hide objects or whole folders. **Select > Reveal Hidden** (Alt+H) brings them back. Every change can be undone with Ctrl+Z and redone with Ctrl+Shift+Z. ## Where you can walk @@ -81,18 +91,18 @@ edges, grey are floors you can't reach. **W** shows or hides it. - The **World** tab shows the area's size and its settings (step height, headroom, body radius). The presets **Open**, **Standard** and **Careful** set them for you. -- **World > Auto-generate Walkable Surfaces** gives every mesh a surface: walkable where it's flat, blocking where +- **Object > Auto-generate Walkable Surfaces** (in the 3D Viewport's header) gives every mesh a surface: walkable where it's flat, blocking where it's steep. A summary shows what it did; **Undo** in it takes back just that run. -- Per object, the **Surface** buttons in the Selected tab decide what it is for the player: +- Per object, the **Surface** buttons in the Object tab decide what it is for the player: **Auto** (decided by its shape), **Surface** (walk on its flat parts, bump into its steep ones), **Collider** (you can't walk through it), **Walk through** (ignored). Right-clicking an object offers the same. -- **Draw Floor** (B, or the brush in the tool strip): select an object, then drag over it to paint walkable floor +- **Draw Floor** (B, the brush in the toolbar, or the **Draw Floor** mode in the header): select an object, then drag over it to paint walkable floor onto it, even on furniture. Shift+drag erases; [ and ] change the brush size. **Fill Flat Faces** paints every face of it that's flat enough at once. ## World items -**World > Add at the View's Centre** places items where the camera looks: +**Add** (in the 3D Viewport's header, or Shift+A over the view) places items where the camera looks: | Item | What it does on the headset | |---|---| @@ -104,11 +114,11 @@ edges, grey are floors you can't reach. **W** shows or hides it. | **Invisible Wall** | stops you; never drawn on the headset. Scale and turn it to fit; where it stands is no longer walkable | | **Gravity Zone** | inside it, "down" is the zone's own: a direction, or any surface you stand on | -Select an item to move it with the gizmo or type its values in the Selected tab. **World > Clear World Layer** +Select an item to move it with the gizmo or type its values in the Object tab. **Object > Clear World Layer** removes them all. Meta's own homes have invisible walls too, round their play space (Cascadia, Space Station, Desert Terrace, Haven). -Frame Studio and Frame Home read them as invisible walls, so you can't walk out past them. Select one in the Explorer +Frame Studio and Frame Home read them as invisible walls, so you can't walk out past them. Select one in the Outliner to delete it, or set its **Role** to Surface, if you want to go further in that home. ## The environment: name, picture, sound @@ -139,7 +149,7 @@ Saved environments are *baked*: everything the headset needs, already in its own ## Bundles A bundle (`.fbundle`) packs several saved environments into one file, to share or install together. Use the -**Bundle** menu or the **Bundle** tab: **New Bundle**, add environments (the open one, from My Environments, or any +**File > Bundle** or the **Bundle** tab in Properties: **New Bundle**, add environments (the open one, from My Environments, or any `.fenv`), **Save Bundle...**, and **Install on Steam Frame...**. Opening a `.fbundle` lists what's in it; double-click one to open it, or **Unpack into My Environments**. See [bundles.md](bundles.md). @@ -155,12 +165,15 @@ The **Headset** tab (or the **Headset** menu): ## Settings and tools -- **Edit > Settings...**: Studio's own (3D view resolution, anti-aliasing, texture size and filtering) and the +- **Edit > Preferences...**: Studio's own (3D view resolution, anti-aliasing, texture size and filtering) and the headset's (read from and written to the Frame). -- **Debug**: views that show how the home is built and what it costs (Wireframe, Meshes, GPU Cost, Overdraw), - **Leave Out** to hide whole kinds of objects, **Home Report...** (what the home is made of and what may be slow) - and **Headset Debug...** (the same views on the headset). -- **View**: **Show Only Selected** (I), **The Home's Meshes**, **World Layer** (W) and **Show Everything**. +- **Viewport shading** (the buttons and ▾ at the right of the 3D Viewport's header): Material (as the headset draws + it), Solid, Wireframe, and in ▾ **GPU Cost**, **Overdraw** and **Leave Out** (hide whole kinds of objects). +- **Window > Home Report...**: what the home is made of and what may be slow. +- **Headset > Headset Debug...**: the same views, on the headset. +- **View** (in the 3D Viewport's header): the toolbar and sidebar, framing, the numpad viewpoints, **Local View** + (show only the selection) and **Show Everything**. +- **Edit > Menu Search...** (F3): find any command by typing part of its name. ## Keyboard shortcuts @@ -168,8 +181,11 @@ The **Headset** tab (or the **Headset** menu): |---|---|---|---| | Ctrl+O | open | Ctrl+S | save | | Ctrl+Shift+S | save as | Ctrl+Z / Ctrl+Shift+Z | undo / redo | -| G / R / S | move / rotate / scale | B | draw floor | -| H / Alt+H | hide / unhide all | X, Delete | delete | -| F / Home | frame selected / all | P, Numpad 0 | player view | -| I | show only selected | W | world layer | -| Esc | deselect | F1 | controls | +| G / R / S | move / rotate / scale tool | B | draw floor | +| Shift+A | add menu at the mouse | X | delete (asks first); Delete: right away | +| H / Alt+H | hide / reveal hidden | Alt+A, Esc | select nothing | +| Numpad . / Home | frame selected / all | Numpad 0, P | player view | +| Numpad 1 / 3 / 7 | front / right / top (Ctrl: the other side) | Numpad /, I | show only selected | +| W | world layer | Space | play / pause | +| T / N | toolbar / sidebar | Ctrl+Space | maximize the 3D Viewport | +| F3 | menu search: every command by name | F1 | controls | diff --git a/docs/troubleshooting.md b/docs/troubleshooting.md index 561fbe5..e5d9b5e 100644 --- a/docs/troubleshooting.md +++ b/docs/troubleshooting.md @@ -32,11 +32,12 @@ If Studio starts but says it couldn't start Vulkan, the message names the `studi ## Blank or black view -- With nothing open, Studio shows its start screen. Open a home with **File > Open Home...**. +- With nothing open, Studio shows its start screen. Open a home with **File > Open...**. - A big home takes a while to load; textures arrive after the shapes. -- Check that things aren't hidden: **View > Show Everything**, and **Edit > Unhide All** (Alt+H). **Show Only - Selected** (I) hides everything else; press I or Esc to show everything again. -- Make sure **Debug** is set to **Normal** and nothing is ticked under **Debug > Leave Out**. +- Check that things aren't hidden: **View > Show Everything**, and **Select > Reveal Hidden** (Alt+H). **Local + View** (Numpad / or I) shows only the selection; press it again or Esc to show everything. +- Make sure the view's shading is **Material** (the sphere buttons at the right of the 3D Viewport's header) and + nothing is ticked under **▾ > Leave Out**. - Use **View > Frame All** (Home key) to bring the whole home into view. ## Dialogs don't appear on Linux diff --git a/docs/using-frame-home.md b/docs/using-frame-home.md index 087a0e0..eb3aa5f 100644 --- a/docs/using-frame-home.md +++ b/docs/using-frame-home.md @@ -99,7 +99,7 @@ More details: ## Settings -The **Settings** page has three groups. Frame Studio shows the same settings under **Edit > Settings...**, in the +The **Settings** page has three groups. Frame Studio shows the same settings under **Edit > Preferences...**, in the "Steam Frame (Frame Home)" part, so you can change them from your computer too. Settings are stored in `~/frame-home/settings.json` on the headset. Frame Home reads it again whenever it changes. @@ -168,4 +168,4 @@ Frame Home restarts. The GPU cost view times every draw, which makes the GPU a little slower while it is on. -Studio can show and change the same page from your computer: **Debug > Headset Debug...**. +Studio can show and change the same page from your computer: **Headset > Headset Debug...**. diff --git a/studio/CMakeLists.txt b/studio/CMakeLists.txt index 7aac378..3aee8d7 100644 --- a/studio/CMakeLists.txt +++ b/studio/CMakeLists.txt @@ -128,6 +128,7 @@ target_include_directories(frame-studio PRIVATE "${TP}/qhe" "${TP}/stb" "${TP}/miniaudio" + "${TP}/inter" "${TP}/acl/includes" "${TP}/rtm/includes" "${TP}/astcenc/Source" diff --git a/studio/studio.cpp b/studio/studio.cpp index 136b660..b79b63b 100644 --- a/studio/studio.cpp +++ b/studio/studio.cpp @@ -443,19 +443,25 @@ ImVec4 hex(uint32_t rgb, float a = 1.0f) { return ImVec4(((rgb >> 16) & 0xFF) / 255.0f, ((rgb >> 8) & 0xFF) / 255.0f, (rgb & 0xFF) / 255.0f, a); } -// One calm, neutral dark palette: greys with a faint cool cast, and one blue accent kept for primary actions, -// selection and progress. Orange stays Frame Studio's own mark (the brand, the badge, the selected mesh). -constexpr uint32_t kPanel = 0x2b2d31, kList = 0x232528, kListAlt = 0x26282c, kBar = 0x1e1f22, kWidget = 0x3c3f45; +// Frame Studio's own dark palette, laid out the way Blender works: areas on a near-black gutter, each with a header +// strip, panels on lighter boxes. Cool neutral greys, one blue for selection and the action a panel is for, and +// orange as Frame Studio's mark (the brand, the selected mesh, the active object). +constexpr uint32_t kPanel = 0x2b2d31, kList = 0x232528, kListAlt = 0x26282c, kBar = 0x1c1d20, kWidget = 0x3c3f45; constexpr uint32_t kWidgetHover = 0x4a4e55, kWidgetActive = 0x55595f; constexpr uint32_t kBlue = 0x3f7bd6, kBlueHover = 0x528ae0, kBlueActive = 0x346ac0, kSelect = 0x2e4a78; constexpr uint32_t kOrange = 0xffa033, kText = 0xe3e5e8, kDim = 0x8b9097, kHeading = 0xb9bec6; -constexpr uint32_t kLine = 0x3a3d43, kSplit = 0x1a1b1e; // hairlines between things, and the panel splitters -constexpr uint32_t kToolBg = 0x24262a, kToolHover = 0x3d4047; // buttons floating over the 3D view +constexpr uint32_t kLine = 0x3a3d43, kSplit = 0x131416; // hairlines between things, and the gutter between areas +constexpr uint32_t kHeader = 0x25272b, kPanelBox = 0x33363c; // an area's header strip; a Properties panel +constexpr uint32_t kViewBg = 0x393b40; // the 3D viewport behind the home +constexpr uint32_t kToolBg = 0x24262a, kToolHover = 0x3d4047; // the viewport's toolbar and navigation buttons constexpr uint32_t kDanger = 0x7a3434, kDangerHover = 0x9a4040; // Delete, Remove, Cancel the load constexpr uint32_t kGo = 0x2f8a4a, kGoHover = 0x3aa35a; // Draw Floor, the chosen walk preset ImU32 col(uint32_t rgb, float a = 1.0f) { return ImGui::ColorConvertFloat4ToU32(hex(rgb, a)); } +#include "inter_regular.h" // Inter (SIL OFL 1.1: third_party/inter/LICENSE.txt), Blender's interface font +#include "inter_semibold.h" + // Fonts beside the body text (main loads them; null when the Windows font is missing, then the body font is used). ImFont* g_fontBold = nullptr; // section headers, the brand ImFont* g_fontTitle = nullptr; // the start screen's title @@ -476,27 +482,29 @@ void pushDanger() { void applyTheme(float scale) { ImGuiStyle& s = ImGui::GetStyle(); - s.WindowRounding = 8; // floating windows; the full-window panels push 0 - s.ChildRounding = 0; - s.FrameRounding = 5; - s.PopupRounding = 6; - s.GrabRounding = 4; - s.TabRounding = 5; - s.ScrollbarRounding = 8; - s.WindowBorderSize = 1; + s.WindowRounding = 6; // areas and floating windows: Blender's rounded corners + s.ChildRounding = 4; + s.FrameRounding = 4; + s.PopupRounding = 5; + s.GrabRounding = 3; + s.TabRounding = 4; + s.ScrollbarRounding = 4; + s.WindowBorderSize = 0; s.ChildBorderSize = 0; s.PopupBorderSize = 1; s.FrameBorderSize = 0; + s.DockingSeparatorSize = 3; // the gutter between areas s.WindowTitleAlign = ImVec2(0.0f, 0.5f); s.WindowMenuButtonPosition = ImGuiDir_None; - s.FramePadding = ImVec2(8, 4); - s.ItemSpacing = ImVec2(6, 5); - s.ItemInnerSpacing = ImVec2(6, 4); - s.WindowPadding = ImVec2(12, 10); - s.CellPadding = ImVec2(6, 3); - s.ScrollbarSize = 10; - s.GrabMinSize = 9; + s.FramePadding = ImVec2(7, 3); // a widget 20 px high: Blender's unit + s.ItemSpacing = ImVec2(4, 3); + s.ItemInnerSpacing = ImVec2(4, 4); + s.WindowPadding = ImVec2(10, 8); + s.CellPadding = ImVec2(5, 2); + s.ScrollbarSize = 8; + s.GrabMinSize = 8; s.IndentSpacing = 14; + s.TabBarBorderSize = 0; s.SeparatorTextBorderSize = 1; s.SeparatorTextPadding = ImVec2(0, 4); s.SeparatorTextAlign = ImVec2(0.0f, 0.5f); @@ -512,8 +520,8 @@ void applyTheme(float scale) { c[ImGuiCol_BorderShadow] = hex(0, 0); c[ImGuiCol_FrameBg] = hex(kWidget); c[ImGuiCol_FrameBgHovered] = hex(kWidgetHover); - c[ImGuiCol_FrameBgActive] = hex(0x1f2124); - c[ImGuiCol_TitleBg] = c[ImGuiCol_TitleBgActive] = c[ImGuiCol_TitleBgCollapsed] = hex(kBar); + c[ImGuiCol_FrameBgActive] = hex(0x1f2124); // a field being typed in: dark + c[ImGuiCol_TitleBg] = c[ImGuiCol_TitleBgActive] = c[ImGuiCol_TitleBgCollapsed] = hex(kHeader); c[ImGuiCol_MenuBarBg] = hex(kBar); c[ImGuiCol_ScrollbarBg] = hex(0, 0); c[ImGuiCol_ScrollbarGrab] = hex(0x4a4d53); @@ -526,17 +534,23 @@ void applyTheme(float scale) { c[ImGuiCol_ButtonHovered] = hex(kWidgetHover); c[ImGuiCol_ButtonActive] = hex(kBlue); c[ImGuiCol_Header] = hex(kSelect); - c[ImGuiCol_HeaderHovered] = hex(0x383b41); - c[ImGuiCol_HeaderActive] = hex(kSelect); + c[ImGuiCol_HeaderHovered] = hex(kBlue, 0.85f); // menu items light up blue + c[ImGuiCol_HeaderActive] = hex(kBlue); c[ImGuiCol_Separator] = c[ImGuiCol_SeparatorHovered] = hex(kLine); c[ImGuiCol_SeparatorActive] = hex(kBlue); c[ImGuiCol_ResizeGrip] = hex(0, 0); c[ImGuiCol_ResizeGripHovered] = hex(kBlue, 0.6f); c[ImGuiCol_ResizeGripActive] = hex(kBlue); - c[ImGuiCol_Tab] = hex(kWidget); + c[ImGuiCol_Tab] = hex(kBar); c[ImGuiCol_TabHovered] = hex(kWidgetHover); - c[ImGuiCol_TabSelected] = hex(kSelect); - c[ImGuiCol_TableHeaderBg] = hex(kBar); + c[ImGuiCol_TabSelected] = hex(kHeader); + c[ImGuiCol_TabSelectedOverline] = hex(0, 0); + c[ImGuiCol_TabDimmed] = hex(kBar); + c[ImGuiCol_TabDimmedSelected] = hex(kHeader); + c[ImGuiCol_TabDimmedSelectedOverline] = hex(0, 0); + c[ImGuiCol_DockingPreview] = hex(kBlue, 0.55f); + c[ImGuiCol_DockingEmptyBg] = hex(kSplit); + c[ImGuiCol_TableHeaderBg] = hex(kHeader); c[ImGuiCol_TableBorderStrong] = c[ImGuiCol_TableBorderLight] = hex(kLine); c[ImGuiCol_TableRowBg] = hex(0, 0); c[ImGuiCol_TableRowBgAlt] = hex(0xffffff, 0.025f); @@ -676,7 +690,6 @@ struct Studio { ImVec2 clickPos; bool clickArmed = false; bool gizmoWasUsing = false; - float outlinerW = 0, propertiesW = 0; // the Explorer (left) and the Inspector (right), dragged by their splitters std::vectorLQ/(J7)&/%vr%mgOT.A+4*&sG`t-;*#wL84P*&^W)..DHPwLtR(+&g&a..KZlwLKgcX;1.]p&"
+ "9vn;Z1BhYZ0]$@0dAk8[>a*T[^gfi0Eig5][:bS]+Z3L,jX`/_7GXM_utI_&t?=d`BCm,agd35/`ZtDaJhMdav4@D3dsT&btei#dU>ql&$M+Tel1c]lLluW_3G&TnW,63'g-&/11?km/"
+ "-AIE3e-wu#p5-N0QYE)#O@dZ&&/@G;n=hB#:S2s](8%Ek*(w&]^Oeeu:*gn8.,8xt>+(ME2MPiw6oGw+v$GTv6o`u#,&3Pti(g94I'6M^V-nwdL#opH@+,4BXY?2*Np;e[5'K`_V-pH^;2=0]VQh@=**"
+ "DXge$o]9Y(k)acWLZI:7V+s''pcO)8Nl%T&m7^V-