SPB Git

spb/metrika Public

Stata-class statistics, GPU-accelerated by Apple Silicon. Native Swift — no Electron, no Python runtime, no compromises.

Swift 92.4% HTML 3.3% R 3% Shell 1.3%
2.3 KB · 86 lines swift
Raw Blame History
1//2//  MetrikaApp.swift3//  Metrika4//5//  Author:  Simon-Pierre Boucher6//  Contact: contact@spboucher.ai7//  Copyright © 2026 Simon-Pierre Boucher. All rights reserved.8//910import SwiftUI1112@main13struct MetrikaApp: App {14    @State private var model = SessionModel()1516    var body: some Scene {17        WindowGroup {18            ContentView()19                .environment(model)20                .frame(minWidth: 900, minHeight: 560)21        }22        .windowStyle(.automatic)23    }24}2526struct ContentView: View {27    enum Pane: String, CaseIterable {28        case console = "Console"29        case data = "Data"30        case doFile = "Do-file"31        case manual = "Manual"32    }3334    @Environment(SessionModel.self) private var model35    @State private var pane: Pane = ContentView.initialPane()3637    /// Debug hook for headless screenshots: METRIKA_AUTOPANE selects the38    /// pane shown at launch.39    private static func initialPane() -> Pane {40        #if DEBUG41        if let name = ProcessInfo.processInfo.environment["METRIKA_AUTOPANE"],42           let selected = Pane(rawValue: name) {43            return selected44        }45        #endif46        return .console47    }4849    var body: some View {50        NavigationSplitView {51            VariablesSidebar()52        } detail: {53            Group {54                switch pane {55                case .console:56                    HSplitView {57                        ConsoleView()58                            .frame(minWidth: 480)59                        if model.lastPlot != nil {60                            PlotView()61                                .frame(minWidth: 300)62                        }63                    }64                case .data:65                    DataBrowserPane()66                case .doFile:67                    DoFileEditorPane()68                case .manual:69                    ManualPane()70                }71            }72            .toolbar {73                ToolbarItem(placement: .principal) {74                    Picker("Pane", selection: $pane) {75                        ForEach(Pane.allCases, id: \.self) { pane in76                            Text(pane.rawValue).tag(pane)77                        }78                    }79                    .pickerStyle(.segmented)80                }81            }82        }83        .navigationTitle("Metrika")84    }85}86