watch: use watch as trackpad
This commit is contained in:
parent
a7619fcc84
commit
f1bf501e88
|
@ -15,12 +15,14 @@
|
|||
"subtype" : "42mm"
|
||||
},
|
||||
{
|
||||
"filename" : "Icon 7.png",
|
||||
"idiom" : "watch",
|
||||
"role" : "companionSettings",
|
||||
"scale" : "2x",
|
||||
"size" : "29x29"
|
||||
},
|
||||
{
|
||||
"filename" : "Icon 6.png",
|
||||
"idiom" : "watch",
|
||||
"role" : "companionSettings",
|
||||
"scale" : "3x",
|
||||
|
|
Binary file not shown.
After Width: | Height: | Size: 5.2 KiB |
Binary file not shown.
After Width: | Height: | Size: 4.1 KiB |
|
@ -9,11 +9,14 @@
|
|||
#import <WatchKit/WatchKit.h>
|
||||
#import <Foundation/Foundation.h>
|
||||
#import <SpriteKit/SpriteKit.h>
|
||||
#import "EmulatorProtocol.h"
|
||||
|
||||
@class WCSession;
|
||||
|
||||
@interface InterfaceController : WKInterfaceController
|
||||
|
||||
@property (class, readonly, strong) id<Emulator> sharedEmulator NS_SWIFT_NAME(emulator);
|
||||
|
||||
- (void)sessionReachabilityDidChange:(WCSession *)session;
|
||||
|
||||
@end
|
||||
|
|
|
@ -11,8 +11,10 @@
|
|||
@import ObjectiveC.runtime;
|
||||
@import WatchConnectivity;
|
||||
|
||||
#import "UIKit+Watch.h"
|
||||
#import "InterfaceController.h"
|
||||
#import "EmulatorProtocol.h"
|
||||
#import "TrackPad.h"
|
||||
|
||||
@interface NSObject (fs_override)
|
||||
+(id)sharedApplication;
|
||||
|
@ -32,15 +34,19 @@
|
|||
-(void)setContentsScale:(CGFloat)value;
|
||||
-(void)setContentsGravity:(NSString*)gravity;
|
||||
-(void)setMinificationFilter:(NSString*)filter;
|
||||
-(void)addTarget:(nullable id)target action:(SEL)action forControlEvents:(NSUInteger)controlEvents;
|
||||
-(void)setIdleTimerDisabled:(BOOL)disabled;
|
||||
@end
|
||||
|
||||
@interface InterfaceController ()
|
||||
|
||||
@end
|
||||
|
||||
static NSObject<Emulator> *sharedEmulator = nil;
|
||||
|
||||
@implementation InterfaceController
|
||||
{
|
||||
NSObject<Emulator> *emulator;
|
||||
|
||||
}
|
||||
|
||||
+ (void)load {
|
||||
|
@ -52,6 +58,10 @@
|
|||
}
|
||||
}
|
||||
|
||||
+ (id<Emulator>)sharedEmulator {
|
||||
return sharedEmulator;
|
||||
}
|
||||
|
||||
- (void)awakeWithContext:(id)context {
|
||||
[super awakeWithContext:context];
|
||||
}
|
||||
|
@ -71,7 +81,7 @@
|
|||
|
||||
}
|
||||
|
||||
- (id)fullScreenView {
|
||||
- (UIView*)fullScreenView {
|
||||
id parentView = [[[[[[NSClassFromString(@"UIApplication") sharedApplication] keyWindow] rootViewController] viewControllers] firstObject] view];
|
||||
id view = [self findDescendantViewOfClass:NSClassFromString(@"SPFullScreenView") inView:parentView]; // watchOS 5
|
||||
if (view == nil) {
|
||||
|
@ -94,21 +104,23 @@
|
|||
|
||||
- (void)didAppear {
|
||||
[self hideTimeLabel];
|
||||
if (emulator == nil) {
|
||||
if (sharedEmulator == nil) {
|
||||
[self loadAndStartEmulator];
|
||||
} else {
|
||||
sharedEmulator.running = YES;
|
||||
}
|
||||
}
|
||||
|
||||
- (void)willActivate {
|
||||
if ([WKExtension sharedExtension].applicationState == WKApplicationStateActive) {
|
||||
emulator.running = YES;
|
||||
sharedEmulator.running = YES;
|
||||
}
|
||||
}
|
||||
|
||||
- (void)didDeactivate {
|
||||
// This method is called when watch view controller is no longer visible
|
||||
[super didDeactivate];
|
||||
emulator.running = NO;
|
||||
sharedEmulator.running = NO;
|
||||
}
|
||||
|
||||
- (void)sessionReachabilityDidChange:(WCSession *)session {
|
||||
|
@ -116,18 +128,26 @@
|
|||
}
|
||||
|
||||
- (void)loadAndStartEmulator {
|
||||
UIView *fullScreenView = [self fullScreenView];
|
||||
Class emulatorClass = NSClassFromString(@"MacPlus4MEmulator");
|
||||
emulator = [emulatorClass new];
|
||||
emulator.rootViewController = nil;
|
||||
emulator.showAlert = ^(NSString *title, NSString *message) {
|
||||
sharedEmulator = [emulatorClass new];
|
||||
sharedEmulator.rootViewController = nil;
|
||||
sharedEmulator.showAlert = ^(NSString *title, NSString *message) {
|
||||
NSLog(@"Alert: %@ - %@", title, message);
|
||||
};
|
||||
emulator.dataPath = [NSBundle mainBundle].resourcePath;
|
||||
emulator.screenLayer = [[self fullScreenView] layer];
|
||||
emulator.speed = emulator.initialSpeed;
|
||||
[emulator.screenLayer setContentsGravity:@"CAGravityResizeAspectFill"];
|
||||
[emulator.screenLayer setAffineTransform:CGAffineTransformScale(CGAffineTransformMakeRotation(M_PI_2), 0.375, 0.375)];
|
||||
[emulator.screenLayer setMinificationFilter:@"CAFilterTrilinear"];
|
||||
[emulator performSelector:@selector(run) withObject:nil afterDelay:0.1];
|
||||
sharedEmulator.dataPath = [NSBundle mainBundle].resourcePath;
|
||||
sharedEmulator.screenLayer = fullScreenView.layer;
|
||||
sharedEmulator.speed = sharedEmulator.initialSpeed;
|
||||
[sharedEmulator.screenLayer setContentsGravity:@"CAGravityResizeAspectFill"];
|
||||
[sharedEmulator.screenLayer setAffineTransform:CGAffineTransformScale(CGAffineTransformMakeRotation(M_PI_2), 0.375, 0.375)];
|
||||
[sharedEmulator.screenLayer setMinificationFilter:@"CAFilterTrilinear"];
|
||||
[sharedEmulator performSelector:@selector(run) withObject:nil afterDelay:0.1];
|
||||
|
||||
id app = [NSClassFromString(@"UIApplication") sharedApplication];
|
||||
[app setIdleTimerDisabled:YES];
|
||||
|
||||
TrackPad *trackpad = [[TrackPad alloc] initWithFrame:fullScreenView.bounds];
|
||||
[fullScreenView addSubview:trackpad];
|
||||
}
|
||||
|
||||
@end
|
||||
|
|
|
@ -0,0 +1,46 @@
|
|||
//
|
||||
// UIKit+Watch.h
|
||||
// Mini vMac
|
||||
//
|
||||
// Created by Jesús A. Álvarez on 2024-03-27.
|
||||
// Copyright © 2024 namedfork. All rights reserved.
|
||||
//
|
||||
|
||||
#ifndef UIKit_Watch_h
|
||||
#define UIKit_Watch_h
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
|
||||
@interface UIResponder : NSObject
|
||||
|
||||
@end
|
||||
|
||||
@interface UIView : UIResponder
|
||||
@property(nonatomic,getter=isMultipleTouchEnabled) BOOL multipleTouchEnabled;
|
||||
@property(nonatomic) CGRect bounds;
|
||||
|
||||
- (instancetype)initWithFrame:(CGRect)frame NS_DESIGNATED_INITIALIZER;
|
||||
|
||||
@end
|
||||
|
||||
@interface UITouch : NSObject
|
||||
|
||||
@property(nonatomic,readonly) CGFloat force;
|
||||
|
||||
- (CGPoint)locationInView:(nullable UIView *)view;
|
||||
- (CGPoint)previousLocationInView:(nullable UIView *)view;
|
||||
|
||||
@end
|
||||
|
||||
@interface UIEvent : NSObject
|
||||
|
||||
@property(nonatomic,readonly) NSTimeInterval timestamp;
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
|
||||
#endif /* UIKit_h */
|
|
@ -45,6 +45,8 @@
|
|||
289673912BB4947A0014D8E7 /* MacPlus4M_WatchOS.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 289673422BB209DB0014D8E7 /* MacPlus4M_WatchOS.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
|
||||
289673942BB494FB0014D8E7 /* Mini vMac WatchKit Extension.appex in Embed App Extensions */ = {isa = PBXBuildFile; fileRef = 2896738E2BB493F80014D8E7 /* Mini vMac WatchKit Extension.appex */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; };
|
||||
289673972BB4958D0014D8E7 /* Mini vMac WatchKit App.app in Embed Watch Content */ = {isa = PBXBuildFile; fileRef = 289673742BB492400014D8E7 /* Mini vMac WatchKit App.app */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; };
|
||||
2896739B2BB4A2E80014D8E7 /* TrackPad.m in Sources */ = {isa = PBXBuildFile; fileRef = 28BA89841CE73E7200A98104 /* TrackPad.m */; };
|
||||
2896739E2BB4A90A0014D8E7 /* disk1.dsk in Resources */ = {isa = PBXBuildFile; fileRef = 2896739D2BB4A90A0014D8E7 /* disk1.dsk */; };
|
||||
289710C31CFB11BF0089D463 /* MYOSGLUE.m in Sources */ = {isa = PBXBuildFile; fileRef = 28CE8ECB1CD4CDC500FE25A8 /* MYOSGLUE.m */; };
|
||||
289710DC1CFB12240089D463 /* Icon.png in Resources */ = {isa = PBXBuildFile; fileRef = 289710D81CFB121F0089D463 /* Icon.png */; };
|
||||
289710DD1CFB12240089D463 /* Icon@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 289710D91CFB121F0089D463 /* Icon@2x.png */; };
|
||||
|
@ -365,6 +367,8 @@
|
|||
289673842BB4937D0014D8E7 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
|
||||
289673852BB4937D0014D8E7 /* Interface.storyboard */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; path = Interface.storyboard; sourceTree = "<group>"; };
|
||||
2896738E2BB493F80014D8E7 /* Mini vMac WatchKit Extension.appex */ = {isa = PBXFileReference; explicitFileType = "wrapper.app-extension"; includeInIndex = 0; path = "Mini vMac WatchKit Extension.appex"; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
2896739C2BB4A4170014D8E7 /* UIKit+Watch.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "UIKit+Watch.h"; sourceTree = "<group>"; };
|
||||
2896739D2BB4A90A0014D8E7 /* disk1.dsk */ = {isa = PBXFileReference; lastKnownFileType = file; path = disk1.dsk; sourceTree = "<group>"; };
|
||||
289710D41CFB11BF0089D463 /* Mac128K.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Mac128K.framework; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
289710D61CFB121F0089D463 /* CNFUDOSG.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = CNFUDOSG.h; sourceTree = "<group>"; };
|
||||
289710D71CFB121F0089D463 /* CNFUDALL.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = CNFUDALL.h; sourceTree = "<group>"; };
|
||||
|
@ -652,6 +656,8 @@
|
|||
2896737F2BB4937D0014D8E7 /* InterfaceController.h */,
|
||||
289673802BB4937D0014D8E7 /* InterfaceController.m */,
|
||||
289673812BB4937D0014D8E7 /* vMac.rom */,
|
||||
2896739D2BB4A90A0014D8E7 /* disk1.dsk */,
|
||||
2896739C2BB4A4170014D8E7 /* UIKit+Watch.h */,
|
||||
);
|
||||
path = "Mini vMac WatchKit Extension";
|
||||
sourceTree = "<group>";
|
||||
|
@ -1320,6 +1326,7 @@
|
|||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
2896738A2BB493A90014D8E7 /* Assets.xcassets in Resources */,
|
||||
2896739E2BB4A90A0014D8E7 /* disk1.dsk in Resources */,
|
||||
2896738D2BB493B20014D8E7 /* vMac.rom in Resources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
|
@ -1594,6 +1601,7 @@
|
|||
isa = PBXSourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
2896739B2BB4A2E80014D8E7 /* TrackPad.m in Sources */,
|
||||
2896738B2BB493AF0014D8E7 /* InterfaceController.m in Sources */,
|
||||
2896738C2BB493AF0014D8E7 /* ExtensionDelegate.m in Sources */,
|
||||
);
|
||||
|
|
|
@ -8,6 +8,11 @@
|
|||
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
#if TARGET_OS_WATCH
|
||||
#import "UIKit+Watch.h"
|
||||
@interface TrackPad : UIView
|
||||
#else
|
||||
@interface TrackPad : UIControl
|
||||
#endif
|
||||
|
||||
@end
|
||||
|
|
|
@ -7,8 +7,14 @@
|
|||
//
|
||||
|
||||
#import "TrackPad.h"
|
||||
#if TARGET_OS_WATCH
|
||||
#import "InterfaceController.h"
|
||||
#define AppDelegate InterfaceController
|
||||
#define AudioServicesPlaySystemSound
|
||||
#else
|
||||
#import "AppDelegate.h"
|
||||
@import AudioToolbox;
|
||||
#endif
|
||||
|
||||
#define TRACKPAD_ACCEL_N 1
|
||||
#define TRACKPAD_ACCEL_T 0.2
|
||||
|
@ -36,6 +42,7 @@
|
|||
return self;
|
||||
}
|
||||
|
||||
#if !TARGET_OS_WATCH
|
||||
- (void)willMoveToSuperview:(UIView *)newSuperview {
|
||||
[super willMoveToSuperview:newSuperview];
|
||||
@try {
|
||||
|
@ -44,9 +51,14 @@
|
|||
supportsForceTouch = NO;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
- (BOOL)isMouseEvent:(UIEvent *)event {
|
||||
#if TARGET_OS_WATCH
|
||||
return NO;
|
||||
#else
|
||||
return event.buttonMask != 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
|
||||
|
@ -54,7 +66,7 @@
|
|||
[self startDragging];
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
[currentTouches unionSet:touches];
|
||||
if (currentTouches.count == 1) {
|
||||
[self firstTouchBegan:touches.anyObject withEvent:event];
|
||||
|
|
Loading…
Reference in New Issue