Commit b7505d4a authored by Felix Paul Kühne's avatar Felix Paul Kühne

iOS Dialog Provider: re-write based on UIAlertViewController for tvOS

Once we drop iOS 7, we can also remove the legacy implementation based on UIAlertView
parent fe32c1c6
...@@ -51,3 +51,6 @@ libios_dialog_provider_plugin_la_LDFLAGS = $(AM_LDFLAGS) -Wl,-framework,UIKit ...@@ -51,3 +51,6 @@ libios_dialog_provider_plugin_la_LDFLAGS = $(AM_LDFLAGS) -Wl,-framework,UIKit
if HAVE_IOS if HAVE_IOS
gui_LTLIBRARIES += libios_dialog_provider_plugin.la gui_LTLIBRARIES += libios_dialog_provider_plugin.la
endif endif
if HAVE_TVOS
gui_LTLIBRARIES += libios_dialog_provider_plugin.la
endif
...@@ -61,13 +61,18 @@ ...@@ -61,13 +61,18 @@
@end @end
#ifndef TARGET_OS_TV
@interface VLCBlockingAlertView : UIAlertView <UIAlertViewDelegate> @interface VLCBlockingAlertView : UIAlertView <UIAlertViewDelegate>
@property (copy, nonatomic) void (^completion)(BOOL, NSInteger); @property (copy, nonatomic) void (^completion)(BOOL, NSInteger);
- (id)initWithTitle:(NSString *)title message:(NSString *)message cancelButtonTitle:(NSString *)cancelButtonTitle otherButtonTitles:(NSArray *)otherButtonTitles; - (id)initWithTitle:(NSString *)title
message:(NSString *)message
cancelButtonTitle:(NSString *)cancelButtonTitle
otherButtonTitles:(NSArray *)otherButtonTitles;
@end @end
#endif
static int OpenIntf(vlc_object_t *); static int OpenIntf(vlc_object_t *);
static void CloseIntf(vlc_object_t *); static void CloseIntf(vlc_object_t *);
...@@ -220,10 +225,10 @@ static int DisplayLogin(vlc_object_t *p_this, const char *type, vlc_value_t prev ...@@ -220,10 +225,10 @@ static int DisplayLogin(vlc_object_t *p_this, const char *type, vlc_value_t prev
intf_sys_t *sys = p_intf->p_sys; intf_sys_t *sys = p_intf->p_sys;
NSDictionary *dict = [sys->displayer displayLogin:DictFromDialogLogin(dialog)]; NSDictionary *dict = [sys->displayer displayLogin:DictFromDialogLogin(dialog)];
if (dict) { if (dict) {
NSString *username = [dict objectForKey:@"username"]; NSString *username = dict[@"username"];
if (username != NULL && username.length > 0) if (username != NULL && username.length > 0)
*dialog->username = strdup([username UTF8String]); *dialog->username = strdup([username UTF8String]);
NSString *password = [dict objectForKey:@"password"]; NSString *password = dict[@"password"];
if (password != NULL && password.length > 0) if (password != NULL && password.length > 0)
*dialog->password = strdup([password UTF8String]); *dialog->password = strdup([password UTF8String]);
} }
...@@ -311,35 +316,134 @@ bool checkProgressPanel (void *priv) ...@@ -311,35 +316,134 @@ bool checkProgressPanel (void *priv)
{ {
VLCAssertIsMainThread(); VLCAssertIsMainThread();
VLCBlockingAlertView *alert = [[VLCBlockingAlertView alloc] initWithTitle:[dialog objectForKey:@"title"] message:[dialog objectForKey:@"message"] delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil]; #if TARGET_OS_TV
UIAlertController *alertController = [UIAlertController alertControllerWithTitle:dialog[@"title"]
message:dialog[@"message"]
preferredStyle:UIAlertControllerStyleAlert];
UIAlertAction *action = [UIAlertAction actionWithTitle:@"OK"
style:UIAlertActionStyleDestructive
handler:^(UIAlertAction * _Nonnull action) {
[action release];
[alertController release];
[dialog release];
}];
[alertController addAction:action];
[alertController setPreferredAction:action];
[[UIApplication sharedApplication].keyWindow.rootViewController presentViewController:alertController animated:YES completion:nil];
#else
VLCBlockingAlertView *alert = [[VLCBlockingAlertView alloc] initWithTitle:dialog[@"title"]
message:dialog[@"message"]
delegate:nil
cancelButtonTitle:@"OK"
otherButtonTitles:nil];
alert.completion = ^(BOOL cancelled, NSInteger buttonIndex) { alert.completion = ^(BOOL cancelled, NSInteger buttonIndex) {
[alert release]; [alert release];
[dialog release]; [dialog release];
}; };
[alert show]; [alert show];
#endif
} }
- (void)displayCritical:(NSDictionary *)dialog - (void)displayCritical:(NSDictionary *)dialog
{ {
VLCAssertIsMainThread(); VLCAssertIsMainThread();
VLCBlockingAlertView *alert = [[VLCBlockingAlertView alloc] initWithTitle:[dialog objectForKey:@"title"] message:[dialog objectForKey:@"message"] delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil]; #if TARGET_OS_TV
UIAlertController *alertController = [UIAlertController alertControllerWithTitle:dialog[@"title"]
message:dialog[@"message"]
preferredStyle:UIAlertControllerStyleAlert];
UIAlertAction *action = [UIAlertAction actionWithTitle:@"OK"
style:UIAlertActionStyleDestructive
handler:^(UIAlertAction * _Nonnull action) {
[action release];
[alertController release];
[dialog release];
}];
[alertController addAction:action];
[alertController setPreferredAction:action];
[[UIApplication sharedApplication].keyWindow.rootViewController presentViewController:alertController animated:YES completion:nil];
#else
VLCBlockingAlertView *alert = [[VLCBlockingAlertView alloc] initWithTitle:dialog[@"title"]
message:dialog[@"message"]
delegate:nil
cancelButtonTitle:@"OK"
otherButtonTitles:nil];
alert.completion = ^(BOOL cancelled, NSInteger buttonIndex) { alert.completion = ^(BOOL cancelled, NSInteger buttonIndex) {
[alert release]; [alert release];
[dialog release]; [dialog release];
}; };
[alert show]; [alert show];
#endif
} }
- (NSNumber *)displayQuestion:(NSDictionary *)dialog - (NSNumber *)displayQuestion:(NSDictionary *)dialog
{ {
#if TARGET_OS_TV
__block int ret = 0;
__block UIAlertController *alertController;
__block UIAlertAction *yesAction;
__block UIAlertAction *noAction;
__block UIAlertAction *cancelAction;
dispatch_semaphore_t sema = dispatch_semaphore_create(0);
dispatch_async(dispatch_get_main_queue(), ^{
alertController = [UIAlertController alertControllerWithTitle:dialog[@"title"]
message:dialog[@"message"]
preferredStyle:UIAlertControllerStyleAlert];
cancelAction = [UIAlertAction actionWithTitle:dialog[@"cancel"]
style:UIAlertActionStyleDestructive
handler:^(UIAlertAction * _Nonnull action) {
ret = 3;
dispatch_semaphore_signal(sema);
}];
[alertController addAction:cancelAction];
yesAction = [UIAlertAction actionWithTitle:dialog[@"yes"]
style:UIAlertActionStyleDestructive
handler:^(UIAlertAction * _Nonnull action) {
ret = 0;
dispatch_semaphore_signal(sema);
}];
[alertController addAction:yesAction];
[alertController setPreferredAction:yesAction];
noAction = [UIAlertAction actionWithTitle:dialog[@"yes"]
style:UIAlertActionStyleDestructive
handler:^(UIAlertAction * _Nonnull action) {
ret = 1;
dispatch_semaphore_signal(sema);
}];
[alertController addAction:noAction];
[[UIApplication sharedApplication].keyWindow.rootViewController presentViewController:alertController animated:YES completion:nil];
});
dispatch_semaphore_wait(sema, DISPATCH_TIME_FOREVER);
[cancelAction release];
[yesAction release];
[noAction release];
[alertController release];
[dialog release];
return @(ret);
#else
__block int ret = 0; __block int ret = 0;
__block VLCBlockingAlertView *alert; __block VLCBlockingAlertView *alert;
dispatch_semaphore_t sema = dispatch_semaphore_create(0); dispatch_semaphore_t sema = dispatch_semaphore_create(0);
dispatch_async(dispatch_get_main_queue(), ^{ dispatch_async(dispatch_get_main_queue(), ^{
alert = [[VLCBlockingAlertView alloc] initWithTitle:[dialog objectForKey:@"title"] message:[dialog objectForKey:@"message"] delegate:nil cancelButtonTitle:[dialog objectForKey:@"cancel"] otherButtonTitles:[dialog objectForKey:@"yes"], [dialog objectForKey:@"no"], nil]; alert = [[VLCBlockingAlertView alloc] initWithTitle:dialog[@"title"] message:dialog[@"message"]
delegate:nil
cancelButtonTitle:dialog[@"cancel"]
otherButtonTitles:dialog[@"yes"], dialog[@"no"], nil];
alert.completion = ^(BOOL cancelled, NSInteger buttonIndex) { alert.completion = ^(BOOL cancelled, NSInteger buttonIndex) {
if (cancelled) if (cancelled)
ret = 3; ret = 3;
...@@ -357,17 +461,68 @@ bool checkProgressPanel (void *priv) ...@@ -357,17 +461,68 @@ bool checkProgressPanel (void *priv)
[dialog release]; [dialog release];
return @(ret); return @(ret);
#endif
} }
- (NSDictionary *)displayLogin:(NSDictionary *)dialog - (NSDictionary *)displayLogin:(NSDictionary *)dialog
{ {
#if TARGET_OS_TV
dispatch_semaphore_t sema = dispatch_semaphore_create(0);
__block UIAlertController *alertController;
__block NSDictionary *dict;
dispatch_async(dispatch_get_main_queue(), ^{
alertController = [UIAlertController alertControllerWithTitle:dialog[@"title"]
message:dialog[@"message"]
preferredStyle:UIAlertControllerStyleAlert];
__block UITextField *usernameField = nil;
__block UITextField *passwordField = nil;
[alertController addTextFieldWithConfigurationHandler:^(UITextField * _Nonnull textField) {
usernameField = textField;
}];
[alertController addTextFieldWithConfigurationHandler:^(UITextField * _Nonnull textField) {
textField.secureTextEntry = YES;
passwordField = textField;
}];
[alertController addAction:[[UIAlertAction actionWithTitle:@"Login"
style:UIAlertActionStyleDefault
handler:^(UIAlertAction * _Nonnull action) {
NSString *user = usernameField.text;
NSString *pass = passwordField.text;
dict = [[NSDictionary dictionaryWithObjectsAndKeys:
user ? user : @"", @"username",
pass ? pass : @"", @"password",
nil] retain];
dispatch_semaphore_signal(sema);
}] autorelease]];
[alertController addAction:[[UIAlertAction actionWithTitle:@"Cancel"
style:UIAlertActionStyleCancel
handler:^(UIAlertAction * _Nonnull action) {
dispatch_semaphore_signal(sema);
}] autorelease]];
[[UIApplication sharedApplication].keyWindow.rootViewController presentViewController:alertController animated:YES completion:nil];
});
dispatch_semaphore_wait(sema, DISPATCH_TIME_FOREVER);
[alertController release];
[dialog release];
return dict;
#else
__block NSDictionary *dict; __block NSDictionary *dict;
__block VLCBlockingAlertView *alert; __block VLCBlockingAlertView *alert;
dispatch_semaphore_t sema = dispatch_semaphore_create(0); dispatch_semaphore_t sema = dispatch_semaphore_create(0);
dispatch_async(dispatch_get_main_queue(), ^{ dispatch_async(dispatch_get_main_queue(), ^{
alert = [[VLCBlockingAlertView alloc] initWithTitle:[dialog objectForKey:@"title"] message:[dialog objectForKey:@"message"] delegate:nil cancelButtonTitle:@"Cancel" otherButtonTitles:@"Login", nil]; alert = [[VLCBlockingAlertView alloc] initWithTitle:dialog[@"title"]
message:dialog[@"message"]
delegate:nil
cancelButtonTitle:@"Cancel"
otherButtonTitles:@"Login", nil];
alert.alertViewStyle = UIAlertViewStyleLoginAndPasswordInput; alert.alertViewStyle = UIAlertViewStyleLoginAndPasswordInput;
alert.completion = ^(BOOL cancelled, NSInteger buttonIndex) { alert.completion = ^(BOOL cancelled, NSInteger buttonIndex) {
if (!cancelled) { if (!cancelled) {
...@@ -390,6 +545,7 @@ bool checkProgressPanel (void *priv) ...@@ -390,6 +545,7 @@ bool checkProgressPanel (void *priv)
[alert release]; [alert release];
[dialog release]; [dialog release];
return dict; return dict;
#endif
} }
- (void)displayProgressBar:(NSDictionary *)dialog - (void)displayProgressBar:(NSDictionary *)dialog
...@@ -428,9 +584,9 @@ bool checkProgressPanel (void *priv) ...@@ -428,9 +584,9 @@ bool checkProgressPanel (void *priv)
*/ */
- (void)execute:(NSDictionary *)dict - (void)execute:(NSDictionary *)dict
{ {
SEL sel = [[dict objectForKey:@"sel"] pointerValue]; SEL sel = [dict[@"sel"] pointerValue];
id *result = [[dict objectForKey:@"result"] pointerValue]; id *result = [dict[@"result"] pointerValue];
id object = [dict objectForKey:@"object"]; id object = dict[@"object"];
NSAssert(sel, @"Try to execute a NULL selector"); NSAssert(sel, @"Try to execute a NULL selector");
...@@ -452,11 +608,19 @@ bool checkProgressPanel (void *priv) ...@@ -452,11 +608,19 @@ bool checkProgressPanel (void *priv)
@end @end
#ifndef TARGET_OS_TV
@implementation VLCBlockingAlertView @implementation VLCBlockingAlertView
- (id)initWithTitle:(NSString *)title message:(NSString *)message cancelButtonTitle:(NSString *)cancelButtonTitle otherButtonTitles:(NSArray *)otherButtonTitles - (id)initWithTitle:(NSString *)title
message:(NSString *)message
cancelButtonTitle:(NSString *)cancelButtonTitle
otherButtonTitles:(NSArray *)otherButtonTitles
{ {
self = [self initWithTitle:title message:message delegate:self cancelButtonTitle:cancelButtonTitle otherButtonTitles:nil]; self = [self initWithTitle:title
message:message
delegate:self
cancelButtonTitle:cancelButtonTitle
otherButtonTitles:nil];
if (self) { if (self) {
for (NSString *buttonTitle in otherButtonTitles) for (NSString *buttonTitle in otherButtonTitles)
...@@ -472,5 +636,6 @@ bool checkProgressPanel (void *priv) ...@@ -472,5 +636,6 @@ bool checkProgressPanel (void *priv)
self.completion = nil; self.completion = nil;
} }
} }
@end @end
#endif
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment