// ContentView.swift // Root layout — workspace header, dynamic panel layout, status bar. import SwiftUI struct ContentView: View { @State private var context = MetalContext() @State private var workspace = WorkspaceManager() @State private var currentMode: EditMode = .object var body: some View { GeometryReader { geo in VStack(spacing: 0) { // ── Workspace header ── WorkspaceHeader( workspace: workspace, currentMode: $currentMode, context: context ) // ── Dynamic workspace layout ── WorkspaceLayoutView( workspace: workspace, context: context ) // ── Status bar ── StatusBar(mode: currentMode, sceneGraph: context.sceneGraph) } } .ignoresSafeArea(.keyboard) .preferredColorScheme(.dark) } } // MARK: - Workspace Header struct WorkspaceHeader: View { let workspace: WorkspaceManager @Binding var currentMode: EditMode let context: MetalContext var body: some View { HStack(spacing: 10) { // App icon Image(systemName: "cube.fill") .font(.title3) .foregroundStyle(.orange) Divider().frame(height: 20) // Workspace tabs ScrollView(.horizontal, showsIndicators: false) { HStack(spacing: 4) { ForEach(WorkspaceType.allCases) { ws in WorkspaceTab( type: ws, isActive: workspace.activeWorkspace == ws ) { workspace.switchWorkspace(to: ws) } } } } Divider().frame(height: 20) // Mode picker Menu { ForEach(EditMode.allCases) { mode in Button { currentMode = mode } label: { Label(mode.rawValue, systemImage: mode.icon) } } } label: { Label(currentMode.rawValue, systemImage: currentMode.icon) .font(.caption.weight(.medium)) .padding(.horizontal, 8) .padding(.vertical, 5) .background(.ultraThinMaterial, in: RoundedRectangle(cornerRadius: 5)) } Divider().frame(height: 20) // Add mesh menu Menu { ForEach(PrimitiveType.allCases) { prim in Button { context.addPrimitive(prim) } label: { Label(prim.rawValue, systemImage: prim.icon) } } } label: { Label("Add", systemImage: "plus.circle") .font(.caption.weight(.medium)) } Button { context.deleteSelected() } label: { Image(systemName: "trash") .font(.caption) } .tint(.secondary) Spacer() // Timeline toggle Button { withAnimation(.easeInOut(duration: 0.2)) { workspace.showTimeline.toggle() } } label: { Image(systemName: "play.rectangle") .font(.caption) .foregroundStyle(workspace.showTimeline ? .orange : .secondary) } } .padding(.horizontal, 12) .padding(.vertical, 6) .background(.ultraThinMaterial) } } // MARK: - Workspace Tab struct WorkspaceTab: View { let type: WorkspaceType let isActive: Bool let action: () -> Void var body: some View { Button(action: action) { HStack(spacing: 4) { Image(systemName: type.icon) .font(.system(size: 10)) Text(type.rawValue) .font(.system(size: 11, weight: isActive ? .semibold : .regular)) } .padding(.horizontal, 10) .padding(.vertical, 5) .background( isActive ? Color.orange.opacity(0.15) : Color.clear, in: RoundedRectangle(cornerRadius: 5) ) .foregroundStyle(isActive ? .orange : .secondary) } .buttonStyle(.plain) } }