TypePHP 编译器 https://swoole.com/aot/
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 

194 lines
6.6 KiB

#include <UIKit/UIKit.h>
#include <phpx.h>
void php_typephp_application_did_launch();
void php_typephp_application_control_activated(php::Int controlId);
static NSString *to_ns_string(const php::Str &value)
{
NSString *result = [[NSString alloc] initWithBytes:value.data()
length:value.length()
encoding:NSUTF8StringEncoding];
return result == nil ? @"" : result;
}
@interface TypePHPUIKitBridge : NSObject <UIApplicationDelegate>
@property(nonatomic, strong) UIWindow *window;
@property(nonatomic, strong) UIViewController *rootViewController;
@property(nonatomic, strong) NSMutableDictionary<NSNumber *, UIView *> *controls;
@property(nonatomic) NSInteger nextControlId;
@property(nonatomic) CGFloat logicalWidth;
@property(nonatomic) CGFloat logicalHeight;
- (void)controlActivated:(UIControl *)sender;
@end
static __strong TypePHPUIKitBridge *bridge = nil;
static __strong NSString *applicationName = nil;
@implementation TypePHPUIKitBridge
- (instancetype)init
{
self = [super init];
if (self != nil) {
self.controls = [[NSMutableDictionary alloc] init];
self.nextControlId = 1;
}
return self;
}
- (BOOL)application:(UIApplication *)application
didFinishLaunchingWithOptions:(NSDictionary<UIApplicationLaunchOptionsKey, id> *)launchOptions
{
(void) application;
(void) launchOptions;
bridge = self;
php_typephp_application_did_launch();
return YES;
}
- (void)controlActivated:(UIControl *)sender
{
php_typephp_application_control_activated(static_cast<php::Int>(sender.tag));
}
@end
static CGRect logical_rect(php::Int x, php::Int y, php::Int width, php::Int height)
{
const CGRect bounds = bridge.rootViewController.view.bounds;
const CGFloat scaleX = CGRectGetWidth(bounds) / bridge.logicalWidth;
const CGFloat scaleY = CGRectGetHeight(bounds) / bridge.logicalHeight;
const CGFloat top = bridge.logicalHeight - static_cast<CGFloat>(y + height);
return CGRectMake(
static_cast<CGFloat>(x) * scaleX,
top * scaleY,
static_cast<CGFloat>(width) * scaleX,
static_cast<CGFloat>(height) * scaleY);
}
static php::Int store_control(UIView *control)
{
const NSInteger controlId = bridge.nextControlId++;
control.tag = controlId;
bridge.controls[@(controlId)] = control;
return static_cast<php::Int>(controlId);
}
void php_ui_app_run(php::Str name)
{
@autoreleasepool {
applicationName = to_ns_string(name);
UIApplicationMain(0, nullptr, nil, NSStringFromClass(TypePHPUIKitBridge.class));
}
}
void php_ui_create_window(php::Str title, php::Int width, php::Int height)
{
@autoreleasepool {
(void) title;
bridge.logicalWidth = static_cast<CGFloat>(width);
bridge.logicalHeight = static_cast<CGFloat>(height);
bridge.window = [[UIWindow alloc] initWithFrame:UIScreen.mainScreen.bounds];
bridge.rootViewController = [[UIViewController alloc] init];
bridge.rootViewController.title = applicationName;
bridge.rootViewController.view.backgroundColor = UIColor.systemBackgroundColor;
bridge.window.rootViewController = bridge.rootViewController;
}
}
php::Int php_ui_add_label(
php::Str text,
php::Int x,
php::Int y,
php::Int width,
php::Int height,
php::Int fontSize,
php::Bool bold)
{
@autoreleasepool {
UILabel *label = [[UILabel alloc] initWithFrame:logical_rect(x, y, width, height)];
label.text = to_ns_string(text);
label.font = bold
? [UIFont systemFontOfSize:static_cast<CGFloat>(fontSize)
weight:UIFontWeightSemibold]
: [UIFont systemFontOfSize:static_cast<CGFloat>(fontSize)];
label.textColor = bold ? UIColor.labelColor : UIColor.secondaryLabelColor;
label.textAlignment = NSTextAlignmentCenter;
label.numberOfLines = 0;
label.adjustsFontSizeToFitWidth = YES;
label.minimumScaleFactor = 0.75;
[bridge.rootViewController.view addSubview:label];
return store_control(label);
}
}
php::Int php_ui_add_button(
php::Str title,
php::Int x,
php::Int y,
php::Int width,
php::Int height,
php::Int style)
{
@autoreleasepool {
UIButton *button = [UIButton buttonWithType:UIButtonTypeSystem];
button.frame = logical_rect(x, y, width, height);
UIButtonConfiguration *configuration;
if (style == 1) {
configuration = [UIButtonConfiguration filledButtonConfiguration];
configuration.baseBackgroundColor = UIColor.systemBlueColor;
configuration.baseForegroundColor = UIColor.whiteColor;
} else if (style == 2) {
configuration = [UIButtonConfiguration tintedButtonConfiguration];
configuration.baseBackgroundColor = UIColor.systemBlueColor;
} else {
configuration = [UIButtonConfiguration grayButtonConfiguration];
}
configuration.title = to_ns_string(title);
configuration.cornerStyle = UIButtonConfigurationCornerStyleLarge;
configuration.contentInsets = NSDirectionalEdgeInsetsMake(12, 18, 12, 18);
button.configuration = configuration;
button.titleLabel.font = [UIFont systemFontOfSize:17 weight:UIFontWeightSemibold];
button.titleLabel.adjustsFontSizeToFitWidth = YES;
button.titleLabel.minimumScaleFactor = 0.75;
button.titleLabel.lineBreakMode = NSLineBreakByTruncatingTail;
[button addTarget:bridge
action:@selector(controlActivated:)
forControlEvents:UIControlEventTouchUpInside];
[bridge.rootViewController.view addSubview:button];
return store_control(button);
}
}
void php_ui_set_control_text(php::Int controlId, php::Str text)
{
@autoreleasepool {
UIView *control = bridge.controls[@(static_cast<NSInteger>(controlId))];
NSString *value = to_ns_string(text);
if ([control isKindOfClass:UILabel.class]) {
((UILabel *) control).text = value;
} else if ([control isKindOfClass:UIButton.class]) {
UIButton *button = (UIButton *) control;
UIButtonConfiguration *configuration = button.configuration;
if (configuration != nil) {
configuration.title = value;
button.configuration = configuration;
} else {
[button setTitle:value forState:UIControlStateNormal];
}
button.accessibilityLabel = value;
}
}
}
void php_ui_show_window()
{
@autoreleasepool {
[bridge.window makeKeyAndVisible];
}
}