mirror of
https://github.com/zydeco/minivmac4ios.git
synced 2025-02-19 07:31:01 +00:00
visionOS: native settings menu
This commit is contained in:
parent
ed99d1bbfb
commit
632f01f169
@ -61,6 +61,7 @@
|
||||
28D3C6152B7681420079E915 /* VisionSupport.swift in Sources */ = {isa = PBXBuildFile; fileRef = 28D3C6142B7681420079E915 /* VisionSupport.swift */; };
|
||||
28D3C6172B76B8970079E915 /* DefaultSceneDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 28D3C6162B76B8970079E915 /* DefaultSceneDelegate.swift */; };
|
||||
28D3C61B2B7781700079E915 /* KeyboardSceneDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 28D3C61A2B7781700079E915 /* KeyboardSceneDelegate.swift */; };
|
||||
28D3C61D2B7795060079E915 /* SettingsMenu.swift in Sources */ = {isa = PBXBuildFile; fileRef = 28D3C61C2B7795060079E915 /* SettingsMenu.swift */; };
|
||||
28D5A3FD1CD6868F001A33F6 /* TouchScreen.m in Sources */ = {isa = PBXBuildFile; fileRef = 28D5A3FC1CD6868E001A33F6 /* TouchScreen.m */; };
|
||||
28E3B7DF251D0F13007C273F /* MOUSEMDV.c in Sources */ = {isa = PBXBuildFile; fileRef = 28E3B7CC251D0F12007C273F /* MOUSEMDV.c */; };
|
||||
28E3B7E0251D0F13007C273F /* MOUSEMDV.c in Sources */ = {isa = PBXBuildFile; fileRef = 28E3B7CC251D0F12007C273F /* MOUSEMDV.c */; };
|
||||
@ -289,6 +290,7 @@
|
||||
28D3C6142B7681420079E915 /* VisionSupport.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VisionSupport.swift; sourceTree = "<group>"; };
|
||||
28D3C6162B76B8970079E915 /* DefaultSceneDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DefaultSceneDelegate.swift; sourceTree = "<group>"; };
|
||||
28D3C61A2B7781700079E915 /* KeyboardSceneDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = KeyboardSceneDelegate.swift; sourceTree = "<group>"; };
|
||||
28D3C61C2B7795060079E915 /* SettingsMenu.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingsMenu.swift; sourceTree = "<group>"; };
|
||||
28D5A3FB1CD6868E001A33F6 /* TouchScreen.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TouchScreen.h; sourceTree = "<group>"; };
|
||||
28D5A3FC1CD6868E001A33F6 /* TouchScreen.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TouchScreen.m; sourceTree = "<group>"; };
|
||||
28E3B7CC251D0F12007C273F /* MOUSEMDV.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = MOUSEMDV.c; sourceTree = "<group>"; };
|
||||
@ -619,6 +621,7 @@
|
||||
28F676C61CD15E0B00FC6FA6 /* ViewController.h */,
|
||||
28F676C71CD15E0B00FC6FA6 /* ViewController.m */,
|
||||
28D3C6142B7681420079E915 /* VisionSupport.swift */,
|
||||
28D3C61C2B7795060079E915 /* SettingsMenu.swift */,
|
||||
28848B601CDE97D600B86C45 /* InsertDiskViewController.h */,
|
||||
28848B611CDE97D600B86C45 /* InsertDiskViewController.m */,
|
||||
28848B631CDE97E900B86C45 /* SettingsViewController.h */,
|
||||
@ -1308,6 +1311,7 @@
|
||||
28BA89881CE73FBC00A98104 /* MNVMApplication.m in Sources */,
|
||||
28F6B4CF1CF77099002D76D0 /* compat.m in Sources */,
|
||||
28F6B4521CF07C48002D76D0 /* UIImage+DiskImageIcon.m in Sources */,
|
||||
28D3C61D2B7795060079E915 /* SettingsMenu.swift in Sources */,
|
||||
28BA897F1CE7315400A98104 /* KBKeyboardLayout.m in Sources */,
|
||||
28D3C61B2B7781700079E915 /* KeyboardSceneDelegate.swift in Sources */,
|
||||
28848B621CDE97D600B86C45 /* InsertDiskViewController.m in Sources */,
|
||||
|
@ -10,7 +10,7 @@
|
||||
@import CoreGraphics;
|
||||
@import QuartzCore;
|
||||
|
||||
typedef enum : NSInteger {
|
||||
typedef NS_ENUM(NSInteger, EmulatorSpeed) {
|
||||
EmulatorSpeedAllOut = -1,
|
||||
EmulatorSpeed1x = 0,
|
||||
EmulatorSpeed2x = 1,
|
||||
@ -18,7 +18,7 @@ typedef enum : NSInteger {
|
||||
EmulatorSpeed8x = 3,
|
||||
EmulatorSpeed16x = 4,
|
||||
EmulatorSpeed32x = 5
|
||||
} EmulatorSpeed;
|
||||
};
|
||||
|
||||
@protocol Emulator <NSObject>
|
||||
|
||||
|
@ -4,5 +4,6 @@
|
||||
|
||||
#import "ViewController.h"
|
||||
#import "AppDelegate.h"
|
||||
#import "EmulatorProtocol.h"
|
||||
#import "KBKeyboardView.h"
|
||||
#import "KBKeyboardLayout.h"
|
||||
|
148
Mini vMac/SettingsMenu.swift
Normal file
148
Mini vMac/SettingsMenu.swift
Normal file
@ -0,0 +1,148 @@
|
||||
//
|
||||
// SettingsMenu.swift
|
||||
// Mini vMac
|
||||
//
|
||||
// Created by Jesús A. Álvarez on 2024-02-10.
|
||||
// Copyright © 2024 namedfork. All rights reserved.
|
||||
//
|
||||
|
||||
import SwiftUI
|
||||
|
||||
|
||||
struct SettingsMenu: View {
|
||||
var body: some View {
|
||||
Menu() {
|
||||
Section("Settings") {
|
||||
SpeedMenu()
|
||||
MachineMenu()
|
||||
DisplayScalingMenu()
|
||||
}
|
||||
} label: {
|
||||
Image(systemName: "gear")
|
||||
}.menuOrder(.fixed)
|
||||
}
|
||||
}
|
||||
|
||||
struct SpeedMenu: View {
|
||||
@AppStorage("speedValue") var currentSpeed: EmulatorSpeed = .speed1x
|
||||
private var currentSpeedImage: String {
|
||||
switch currentSpeed {
|
||||
case .speed1x:
|
||||
"tortoise"
|
||||
case .speedAllOut:
|
||||
"hare"
|
||||
case .speed2x:
|
||||
"2.square"
|
||||
case .speed4x:
|
||||
"4.square"
|
||||
case .speed8x:
|
||||
"8.square"
|
||||
case .speed16x:
|
||||
"16.square"
|
||||
case .speed32x:
|
||||
"32.square"
|
||||
@unknown default:
|
||||
"hare"
|
||||
}
|
||||
}
|
||||
var body: some View {
|
||||
Menu("Speed", systemImage:currentSpeedImage) {
|
||||
SpeedButton(label: "1x", speed: .speed1x)
|
||||
SpeedButton(label: "2x", speed: .speed2x)
|
||||
SpeedButton(label: "4x", speed: .speed4x)
|
||||
SpeedButton(label: "8x", speed: .speed8x)
|
||||
SpeedButton(label: "16x", speed: .speed16x)
|
||||
SpeedButton(label: "32x", speed: .speed32x)
|
||||
SpeedButton(label: "Unlimited", speed: .speedAllOut)
|
||||
}.menuOrder(.fixed)
|
||||
}
|
||||
}
|
||||
|
||||
struct SpeedButton: View {
|
||||
@AppStorage("speedValue") var currentSpeed: EmulatorSpeed = .speed1x
|
||||
let label: LocalizedStringKey
|
||||
let speed: EmulatorSpeed
|
||||
var body: some View {
|
||||
if currentSpeed == speed {
|
||||
Button(label, systemImage: "checkmark") {}
|
||||
} else {
|
||||
Button {
|
||||
currentSpeed = speed
|
||||
} label: {
|
||||
Text(label)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct MachineMenu: View {
|
||||
@AppStorage("machine") var currentMachine: String = "Plus4M"
|
||||
let bundles = AppDelegate.shared.emulatorBundles?.sorted(by: { $0.bundleIdentifier! < $1.bundleIdentifier! }) ?? []
|
||||
var body: some View {
|
||||
Menu("Machine", systemImage: "desktopcomputer") {
|
||||
ForEach(bundles, id: \.bundleIdentifier) { bundle in
|
||||
MachineButton(bundle: bundle)
|
||||
}
|
||||
}.menuOrder(.fixed)
|
||||
}
|
||||
}
|
||||
|
||||
struct MachineButton: View {
|
||||
@AppStorage("machine") var currentMachine: String = "Plus4M"
|
||||
var bundle: Bundle
|
||||
var body: some View {
|
||||
if currentMachine == bundle.name {
|
||||
Label {
|
||||
Text("\(bundle.displayName ?? bundle.name)\n\(bundle.getInfoString ?? "")")
|
||||
} icon: {
|
||||
Image(systemName: "checkmark")
|
||||
}
|
||||
} else {
|
||||
Button {
|
||||
if !AppDelegate.emulator.anyDiskInserted {
|
||||
currentMachine = bundle.name
|
||||
AppDelegate.shared.loadAndStartEmulator()
|
||||
}
|
||||
} label: {
|
||||
Text("\(bundle.displayName ?? bundle.name)\n\(bundle.getInfoString ?? "")")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fileprivate extension Bundle {
|
||||
var name: String { ((self.bundlePath as NSString).lastPathComponent as NSString).deletingPathExtension }
|
||||
var displayName: String? { self.object(forInfoDictionaryKey: "CFBundleDisplayName") as? String }
|
||||
var getInfoString: String? { self.object(forInfoDictionaryKey: "CFBundleGetInfoString") as? String }
|
||||
}
|
||||
|
||||
struct DisplayScalingMenu: View {
|
||||
@AppStorage("screenFilter") var scalingFilter: CALayerContentsFilter = .nearest
|
||||
static let filters = [
|
||||
DisplayScalingFilter(filter: .nearest, name: "Nearest"),
|
||||
DisplayScalingFilter(filter: .linear, name: "Linear"),
|
||||
DisplayScalingFilter(filter: .trilinear, name: "Trilinear"),
|
||||
]
|
||||
var body: some View {
|
||||
Menu("Display Scaling", systemImage: "rectangle.and.text.magnifyingglass") {
|
||||
ForEach(DisplayScalingMenu.filters, id: \.filter) { filter in
|
||||
if scalingFilter == filter.filter {
|
||||
Label {
|
||||
Text(filter.name)
|
||||
} icon: {
|
||||
Image(systemName: "checkmark")
|
||||
}
|
||||
} else {
|
||||
Button(filter.name) {
|
||||
scalingFilter = filter.filter
|
||||
}
|
||||
}
|
||||
}
|
||||
}.menuOrder(.fixed)
|
||||
}
|
||||
}
|
||||
|
||||
struct DisplayScalingFilter {
|
||||
let filter: CALayerContentsFilter
|
||||
let name: String
|
||||
}
|
@ -20,11 +20,7 @@ extension ViewController {
|
||||
VStack {
|
||||
Spacer(minLength: 80.0)
|
||||
HStack {
|
||||
Button(action: {
|
||||
AppDelegate.shared.showSettings(self)
|
||||
}, label: {
|
||||
Image(systemName: "gear")
|
||||
}).glassBackgroundEffect()
|
||||
SettingsMenu().glassBackgroundEffect()
|
||||
|
||||
Button(action: {
|
||||
AppDelegate.shared.showInsertDisk(self)
|
||||
|
Loading…
x
Reference in New Issue
Block a user