diff --git a/Classes/AboutView.m b/Classes/AboutView.m index 02a32b4b0..78a427e93 100644 --- a/Classes/AboutView.m +++ b/Classes/AboutView.m @@ -65,6 +65,7 @@ static UICompositeViewDescription *compositeDescription = nil; compositeDescription = [[UICompositeViewDescription alloc] init:self.class statusBar:StatusBarView.class tabBar:TabBarView.class + sideMenu:SideMenuView.class fullscreen:false landscapeMode:LinphoneManager.runningOnIpad portraitMode:true]; diff --git a/Classes/AssistantView.m b/Classes/AssistantView.m index 4231c235b..fe9b64913 100644 --- a/Classes/AssistantView.m +++ b/Classes/AssistantView.m @@ -64,6 +64,7 @@ static UICompositeViewDescription *compositeDescription = nil; compositeDescription = [[UICompositeViewDescription alloc] init:self.class statusBar:StatusBarView.class tabBar:nil + sideMenu:SideMenuView.class fullscreen:false landscapeMode:LinphoneManager.runningOnIpad portraitMode:true]; diff --git a/Classes/CallIncomingView.m b/Classes/CallIncomingView.m index 616c0cba4..1ea0fff63 100644 --- a/Classes/CallIncomingView.m +++ b/Classes/CallIncomingView.m @@ -51,6 +51,7 @@ static UICompositeViewDescription *compositeDescription = nil; compositeDescription = [[UICompositeViewDescription alloc] init:self.class statusBar:StatusBarView.class tabBar:nil + sideMenu:SideMenuView.class fullscreen:false landscapeMode:LinphoneManager.runningOnIpad portraitMode:true]; diff --git a/Classes/CallOutgoingView.m b/Classes/CallOutgoingView.m index b79033c1f..dd086198d 100644 --- a/Classes/CallOutgoingView.m +++ b/Classes/CallOutgoingView.m @@ -31,6 +31,7 @@ static UICompositeViewDescription *compositeDescription = nil; compositeDescription = [[UICompositeViewDescription alloc] init:self.class statusBar:StatusBarView.class tabBar:nil + sideMenu:SideMenuView.class fullscreen:false landscapeMode:LinphoneManager.runningOnIpad portraitMode:true]; diff --git a/Classes/CallSideMenuView.h b/Classes/CallSideMenuView.h new file mode 100644 index 000000000..b3b40a169 --- /dev/null +++ b/Classes/CallSideMenuView.h @@ -0,0 +1,20 @@ +// +// SideMenuViewController.h +// linphone +// +// Created by Gautier Pelloux-Prayer on 28/07/15. +// +// + +#import + +#import "SideMenuTableView.h" +#import "PhoneMainView.h" + +@interface CallSideMenuView : UIViewController + +@property(weak, nonatomic) IBOutlet UILabel *statsLabel; + +- (IBAction)onLateralSwipe:(id)sender; + +@end diff --git a/Classes/CallSideMenuView.m b/Classes/CallSideMenuView.m new file mode 100644 index 000000000..2407f6e07 --- /dev/null +++ b/Classes/CallSideMenuView.m @@ -0,0 +1,147 @@ +// +// SideMenuViewController.m +// linphone +// +// Created by Gautier Pelloux-Prayer on 28/07/15. +// +// + +#import "CallSideMenuView.h" +#import "LinphoneManager.h" +#import "PhoneMainView.h" + +@implementation CallSideMenuView { + NSTimer *updateTimer; +} + +#pragma mark - ViewController Functions + +- (void)viewWillAppear:(BOOL)animated { + [super viewWillAppear:animated]; + updateTimer = + [NSTimer scheduledTimerWithTimeInterval:1 target:self selector:@selector(updateStats) userInfo:nil repeats:YES]; + [self updateStats]; +} + +- (void)viewWillDisappear:(BOOL)animated { + [super viewWillDisappear:animated]; + if (updateTimer != nil) { + [updateTimer invalidate]; + updateTimer = nil; + } +} + +- (IBAction)onLateralSwipe:(id)sender { + [PhoneMainView.instance.mainViewController hideSideMenu:YES]; +} + ++ (NSString *)iceToString:(LinphoneIceState)state { + switch (state) { + case LinphoneIceStateNotActivated: + return NSLocalizedString(@"Not activated", @"ICE has not been activated for this call"); + break; + case LinphoneIceStateFailed: + return NSLocalizedString(@"Failed", @"ICE processing has failed"); + break; + case LinphoneIceStateInProgress: + return NSLocalizedString(@"In progress", @"ICE process is in progress"); + break; + case LinphoneIceStateHostConnection: + return NSLocalizedString(@"Direct connection", + @"ICE has established a direct connection to the remote host"); + break; + case LinphoneIceStateReflexiveConnection: + return NSLocalizedString( + @"NAT(s) connection", + @"ICE has established a connection to the remote host through one or several NATs"); + break; + case LinphoneIceStateRelayConnection: + return NSLocalizedString(@"Relay connection", @"ICE has established a connection through a relay"); + break; + } +} + +- (NSString *)updateStatsForCall:(LinphoneCall *)call stream:(LinphoneStreamType)stream { + NSMutableString *result = [[NSMutableString alloc] init]; + const PayloadType *payload; + const LinphoneCallStats *stats; + const LinphoneCallParams *params = linphone_call_get_current_params(call); + + [result appendString:@"\n"]; + + switch (stream) { + case LinphoneStreamTypeAudio: + [result appendString:@"Audio"]; + payload = linphone_call_params_get_used_audio_codec(params); + stats = linphone_call_get_audio_stats(call); + break; + case LinphoneStreamTypeText: + [result appendString:@"Text"]; + payload = linphone_call_params_get_used_text_codec(params); + stats = linphone_call_get_text_stats(call); + break; + case LinphoneStreamTypeVideo: + [result appendString:@"Video"]; + payload = linphone_call_params_get_used_video_codec(params); + stats = linphone_call_get_video_stats(call); + break; + case LinphoneStreamTypeUnknown: + return @"Unsupported stream type"; + } + [result appendString:@"\n"]; + + if (payload == NULL) { + [result appendString:NSLocalizedString(@"Not enabled yet", nil)]; + [result appendString:@"\n"]; + return result; + } + + [result appendString:[NSString stringWithFormat:@"Codec: %s/%iHz", payload->mime_type, payload->clock_rate]]; + if (stream == LinphoneStreamTypeAudio) { + [result appendString:[NSString stringWithFormat:@"/%i channels", payload->channels]]; + } + [result appendString:@"\n"]; + + if (stats != NULL) { + [result appendString:[NSString stringWithFormat:@"Upload bandwidth: %1.1f kbits/s", stats->upload_bandwidth]]; + [result appendString:@"\n"]; + [result + appendString:[NSString stringWithFormat:@"Download bandwidth: %1.1f kbits/s", stats->download_bandwidth]]; + [result appendString:@"\n"]; + [result appendString:[NSString stringWithFormat:@"ICE state: %@", [self.class iceToString:stats->ice_state]]]; + [result appendString:@"\n"]; + + if (stream == LinphoneStreamTypeVideo) { + MSVideoSize sentSize = linphone_call_params_get_sent_video_size(params); + MSVideoSize recvSize = linphone_call_params_get_received_video_size(params); + float sentFPS = linphone_call_params_get_sent_framerate(params); + float recvFPS = linphone_call_params_get_received_framerate(params); + [result appendString:[NSString stringWithFormat:@"Sent video resolution: %dx%d (%.1fFPS)", sentSize.width, + sentSize.height, sentFPS]]; + [result appendString:@"\n"]; + [result appendString:[NSString stringWithFormat:@"Received video resolution: %dx%d (%.1fFPS)", + recvSize.width, recvSize.height, recvFPS]]; + [result appendString:@"\n"]; + } + } + return result; +} + +- (void)updateStats { + LinphoneCall *call = linphone_core_get_current_call([LinphoneManager getLc]); + + if (!call) { + _statsLabel.text = NSLocalizedString(@"No call in progress", nil); + return; + } + + NSMutableString *stats = [[NSMutableString alloc] init]; + + [stats appendString:[self updateStatsForCall:call stream:LinphoneStreamTypeAudio]]; + [stats appendString:[self updateStatsForCall:call stream:LinphoneStreamTypeVideo]]; + [stats appendString:[self updateStatsForCall:call stream:LinphoneStreamTypeText]]; + + _statsLabel.text = stats; +} + +@end diff --git a/Classes/CallSideMenuView.xib b/Classes/CallSideMenuView.xib new file mode 100644 index 000000000..efe501257 --- /dev/null +++ b/Classes/CallSideMenuView.xib @@ -0,0 +1,55 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Classes/CallView.m b/Classes/CallView.m index 9e7da6abf..958db489b 100644 --- a/Classes/CallView.m +++ b/Classes/CallView.m @@ -25,6 +25,7 @@ #import #import "CallView.h" +#import "CallSideMenuView.h" #import "LinphoneManager.h" #import "PhoneMainView.h" #import "Utils.h" @@ -57,6 +58,7 @@ static UICompositeViewDescription *compositeDescription = nil; compositeDescription = [[UICompositeViewDescription alloc] init:self.class statusBar:StatusBarView.class tabBar:nil + sideMenu:CallSideMenuView.class fullscreen:false landscapeMode:false portraitMode:true]; @@ -328,6 +330,9 @@ static UICompositeViewDescription *compositeDescription = nil; _callView.frame = newFrame; [UIView commitAnimations]; + + // UICompositeView *cvc = PhoneMainView.instance.mainViewController; + // [cvc hideSideMenu:YES]; } } diff --git a/Classes/ChatConversationCreateView.m b/Classes/ChatConversationCreateView.m index 8263661bf..eca01266c 100644 --- a/Classes/ChatConversationCreateView.m +++ b/Classes/ChatConversationCreateView.m @@ -20,6 +20,7 @@ static UICompositeViewDescription *compositeDescription = nil; compositeDescription = [[UICompositeViewDescription alloc] init:self.class statusBar:StatusBarView.class tabBar:TabBarView.class + sideMenu:SideMenuView.class fullscreen:false landscapeMode:false portraitMode:true]; diff --git a/Classes/ChatConversationView.m b/Classes/ChatConversationView.m index ffb8383ce..121780d9e 100644 --- a/Classes/ChatConversationView.m +++ b/Classes/ChatConversationView.m @@ -57,6 +57,7 @@ static UICompositeViewDescription *compositeDescription = nil; compositeDescription = [[UICompositeViewDescription alloc] init:self.class statusBar:StatusBarView.class tabBar:TabBarView.class + sideMenu:SideMenuView.class fullscreen:false landscapeMode:false portraitMode:true]; diff --git a/Classes/ChatsListView.m b/Classes/ChatsListView.m index b0a9c5292..214b9d7bd 100644 --- a/Classes/ChatsListView.m +++ b/Classes/ChatsListView.m @@ -56,6 +56,7 @@ static UICompositeViewDescription *compositeDescription = nil; compositeDescription = [[UICompositeViewDescription alloc] init:self.class statusBar:StatusBarView.class tabBar:TabBarView.class + sideMenu:SideMenuView.class fullscreen:false landscapeMode:LinphoneManager.runningOnIpad portraitMode:true]; diff --git a/Classes/ContactDetailsView.m b/Classes/ContactDetailsView.m index fdd7dfc8e..d08678f34 100644 --- a/Classes/ContactDetailsView.m +++ b/Classes/ContactDetailsView.m @@ -188,6 +188,7 @@ static UICompositeViewDescription *compositeDescription = nil; compositeDescription = [[UICompositeViewDescription alloc] init:self.class statusBar:StatusBarView.class tabBar:TabBarView.class + sideMenu:SideMenuView.class fullscreen:false landscapeMode:LinphoneManager.runningOnIpad portraitMode:true]; diff --git a/Classes/ContactsListView.m b/Classes/ContactsListView.m index c4ef44c9c..b578daf52 100644 --- a/Classes/ContactsListView.m +++ b/Classes/ContactsListView.m @@ -94,6 +94,7 @@ static UICompositeViewDescription *compositeDescription = nil; compositeDescription = [[UICompositeViewDescription alloc] init:self.class statusBar:StatusBarView.class tabBar:TabBarView.class + sideMenu:SideMenuView.class fullscreen:false landscapeMode:LinphoneManager.runningOnIpad portraitMode:true]; diff --git a/Classes/DialerView.m b/Classes/DialerView.m index d3c29ddc6..5429c429f 100644 --- a/Classes/DialerView.m +++ b/Classes/DialerView.m @@ -76,6 +76,7 @@ static UICompositeViewDescription *compositeDescription = nil; compositeDescription = [[UICompositeViewDescription alloc] init:self.class statusBar:StatusBarView.class tabBar:TabBarView.class + sideMenu:SideMenuView.class fullscreen:false landscapeMode:LinphoneManager.runningOnIpad portraitMode:true]; diff --git a/Classes/HistoryDetailsView.m b/Classes/HistoryDetailsView.m index 4ea646623..29cb5ea78 100644 --- a/Classes/HistoryDetailsView.m +++ b/Classes/HistoryDetailsView.m @@ -32,6 +32,7 @@ static UICompositeViewDescription *compositeDescription = nil; compositeDescription = [[UICompositeViewDescription alloc] init:self.class statusBar:StatusBarView.class tabBar:TabBarView.class + sideMenu:SideMenuView.class fullscreen:false landscapeMode:LinphoneManager.runningOnIpad portraitMode:true]; diff --git a/Classes/HistoryListView.m b/Classes/HistoryListView.m index 2e848be6a..ee39e5ac9 100644 --- a/Classes/HistoryListView.m +++ b/Classes/HistoryListView.m @@ -33,6 +33,7 @@ static UICompositeViewDescription *compositeDescription = nil; compositeDescription = [[UICompositeViewDescription alloc] init:self.class statusBar:StatusBarView.class tabBar:TabBarView.class + sideMenu:SideMenuView.class fullscreen:false landscapeMode:LinphoneManager.runningOnIpad portraitMode:true]; diff --git a/Classes/ImagePickerView.m b/Classes/ImagePickerView.m index 501cba77e..40860469a 100644 --- a/Classes/ImagePickerView.m +++ b/Classes/ImagePickerView.m @@ -52,6 +52,7 @@ static UICompositeViewDescription *compositeDescription = nil; compositeDescription = [[UICompositeViewDescription alloc] init:self.class statusBar:StatusBarView.class tabBar:nil + sideMenu:SideMenuView.class fullscreen:false landscapeMode:LinphoneManager.runningOnIpad portraitMode:true]; diff --git a/Classes/ImageView.m b/Classes/ImageView.m index f91350d43..28748683c 100644 --- a/Classes/ImageView.m +++ b/Classes/ImageView.m @@ -121,6 +121,7 @@ static UICompositeViewDescription *compositeDescription = nil; compositeDescription = [[UICompositeViewDescription alloc] init:self.class statusBar:StatusBarView.class tabBar:nil + sideMenu:SideMenuView.class fullscreen:false landscapeMode:LinphoneManager.runningOnIpad portraitMode:true]; diff --git a/Classes/LinphoneUI/Base.lproj/StatusBarView.xib b/Classes/LinphoneUI/Base.lproj/StatusBarView.xib index 8bcf7bea8..171233ae8 100644 --- a/Classes/LinphoneUI/Base.lproj/StatusBarView.xib +++ b/Classes/LinphoneUI/Base.lproj/StatusBarView.xib @@ -7,7 +7,7 @@ - + @@ -30,11 +30,6 @@ - + @@ -98,7 +103,6 @@ - diff --git a/Classes/LinphoneUI/Base.lproj/UICompositeView.xib b/Classes/LinphoneUI/Base.lproj/UICompositeView.xib index b0f342365..34e43e2c9 100644 --- a/Classes/LinphoneUI/Base.lproj/UICompositeView.xib +++ b/Classes/LinphoneUI/Base.lproj/UICompositeView.xib @@ -1,6 +1,7 @@ + @@ -40,15 +41,15 @@ - diff --git a/Classes/LinphoneUI/StatusBarView.h b/Classes/LinphoneUI/StatusBarView.h index 5fa0cdd4a..5df0c8a76 100644 --- a/Classes/LinphoneUI/StatusBarView.h +++ b/Classes/LinphoneUI/StatusBarView.h @@ -26,9 +26,9 @@ } @property(weak, nonatomic) IBOutlet UIButton *registrationState; -@property(nonatomic, strong) IBOutlet UIImageView *callQualityImage; @property(nonatomic, strong) IBOutlet UIButton *callSecurityButton; @property(weak, nonatomic) IBOutlet UIButton *voicemailButton; +@property(weak, nonatomic) IBOutlet UIButton *callQualityButton; @property(weak, nonatomic) IBOutlet UIView *incallView; @property(weak, nonatomic) IBOutlet UIView *outcallView; diff --git a/Classes/LinphoneUI/StatusBarView.m b/Classes/LinphoneUI/StatusBarView.m index 747f694e2..1ee4629c9 100644 --- a/Classes/LinphoneUI/StatusBarView.m +++ b/Classes/LinphoneUI/StatusBarView.m @@ -28,10 +28,6 @@ int messagesUnreadCount; } -@synthesize registrationState; -@synthesize callQualityImage; -@synthesize callSecurityButton; - #pragma mark - Lifecycle Functions - (void)dealloc { @@ -201,9 +197,9 @@ image = [UIImage imageNamed:@"led_connected.png"]; break; } - [registrationState setTitle:message forState:UIControlStateNormal]; - registrationState.accessibilityValue = message; - [registrationState setImage:image forState:UIControlStateNormal]; + [_registrationState setTitle:message forState:UIControlStateNormal]; + _registrationState.accessibilityValue = message; + [_registrationState setImage:image forState:UIControlStateNormal]; } #pragma mark - @@ -216,7 +212,7 @@ _outcallView.hidden = inCall; _incallView.hidden = !inCall; // always hide icons at start since they are not ready yet - callQualityImage.hidden = callSecurityButton.hidden = YES; + _callQualityButton.hidden = _callSecurityButton.hidden = YES; if (callQualityTimer) { [callQualityTimer invalidate]; @@ -252,7 +248,7 @@ [securityDialog dismiss]; } } else { - callSecurityButton.hidden = NO; + _callSecurityButton.hidden = NO; while (list != NULL) { LinphoneCall *call = (LinphoneCall *)list->data; LinphoneMediaEncryption enc = @@ -267,7 +263,7 @@ list = list->next; } NSString *imageName = security ? (pending ? @"security_pending.png" : @"security_ok.png") : @"security_ko.png"; - [callSecurityButton setImage:[UIImage imageNamed:imageName] forState:UIControlStateNormal]; + [_callSecurityButton setImage:[UIImage imageNamed:imageName] forState:UIControlStateNormal]; } } @@ -276,13 +272,14 @@ if (call != NULL) { int quality = MIN(4, floor(linphone_call_get_average_quality(call))); NSString *accessibilityValue = [NSString stringWithFormat:NSLocalizedString(@"Call quality: %d", nil), quality]; - if (![accessibilityValue isEqualToString:callQualityImage.accessibilityValue]) { - callQualityImage.accessibilityValue = accessibilityValue; - callQualityImage.hidden = (quality == -1.f); - callQualityImage.image = + if (![accessibilityValue isEqualToString:_callQualityButton.accessibilityValue]) { + _callQualityButton.accessibilityValue = accessibilityValue; + _callQualityButton.hidden = (quality == -1.f); + UIImage *image = (quality == -1.f) ? nil : [UIImage imageNamed:[NSString stringWithFormat:@"call_quality_indicator_%d.png", quality]]; + [_callQualityButton setImage:image forState:UIControlStateNormal]; } } } @@ -321,11 +318,7 @@ - (IBAction)onSideMenuClick:(id)sender { UICompositeView *cvc = PhoneMainView.instance.mainViewController; - if (cvc.sideMenuView.hidden) { - [cvc hideSideMenu:NO]; - } else { - [cvc hideSideMenu:cvc.sideMenuView.frame.origin.x == 0]; - } + [cvc hideSideMenu:(cvc.sideMenuView.frame.origin.x == 0)]; } - (IBAction)onRegistrationStateClick:(id)sender { diff --git a/Classes/LinphoneUI/UICompositeView.h b/Classes/LinphoneUI/UICompositeView.h index aadd64b8d..8be0f04f9 100644 --- a/Classes/LinphoneUI/UICompositeView.h +++ b/Classes/LinphoneUI/UICompositeView.h @@ -29,9 +29,11 @@ @property(strong) NSString *content; @property(strong) NSString *statusBar; -@property(assign) BOOL statusBarEnabled; @property(strong) NSString *tabBar; +@property(strong) NSString *sideMenu; +@property(assign) BOOL statusBarEnabled; @property(assign) BOOL tabBarEnabled; +@property(assign) BOOL sideMenuEnabled; @property(assign) BOOL fullscreen; @property(assign) BOOL landscapeMode; @property(assign) BOOL portraitMode; @@ -42,6 +44,7 @@ - (id)init:(Class)content statusBar:(Class)statusBar tabBar:(Class)tabBar + sideMenu:(Class)sideMenu fullscreen:(BOOL)fullscreen landscapeMode:(BOOL)landscapeMode portraitMode:(BOOL)portraitMode; diff --git a/Classes/LinphoneUI/UICompositeView.m b/Classes/LinphoneUI/UICompositeView.m index 6afc25fee..5be68c094 100644 --- a/Classes/LinphoneUI/UICompositeView.m +++ b/Classes/LinphoneUI/UICompositeView.m @@ -29,9 +29,11 @@ UICompositeViewDescription *copy = [UICompositeViewDescription alloc]; copy.content = self.content; copy.statusBar = self.statusBar; - copy.statusBarEnabled = self.statusBarEnabled; copy.tabBar = self.tabBar; + copy.sideMenu = self.sideMenu; + copy.statusBarEnabled = self.statusBarEnabled; copy.tabBarEnabled = self.tabBarEnabled; + copy.sideMenuEnabled = self.sideMenuEnabled; copy.fullscreen = self.fullscreen; copy.landscapeMode = self.landscapeMode; copy.portraitMode = self.portraitMode; @@ -46,14 +48,17 @@ - (id)init:(Class)content statusBar:(Class)statusBar tabBar:(Class)tabBar + sideMenu:(Class)sideMenu fullscreen:(BOOL)fullscreen landscapeMode:(BOOL)landscapeMode portraitMode:(BOOL)portraitMode { self.content = NSStringFromClass(content); self.statusBar = NSStringFromClass(statusBar); - self.statusBarEnabled = YES; self.tabBar = NSStringFromClass(tabBar); + self.sideMenu = NSStringFromClass(sideMenu); + self.statusBarEnabled = YES; self.tabBarEnabled = YES; + self.sideMenuEnabled = NO; self.fullscreen = fullscreen; self.landscapeMode = landscapeMode; self.portraitMode = portraitMode; @@ -139,9 +144,6 @@ the device screen size at load */ [self updateViewsFramesAccordingToLaunchOrientation]; [super viewDidLoad]; - - _sideMenuViewController = [self getCachedController:NSStringFromClass(SideMenuView.class)]; - [UICompositeView addSubView:_sideMenuViewController view:self.sideMenuView]; } - (void)viewWillAppear:(BOOL)animated { @@ -205,7 +207,7 @@ [self.tabBarViewController willAnimateRotationToInterfaceOrientation:toInterfaceOrientation duration:duration]; [self.statusBarViewController willAnimateRotationToInterfaceOrientation:toInterfaceOrientation duration:duration]; [self.sideMenuViewController willAnimateRotationToInterfaceOrientation:toInterfaceOrientation duration:duration]; - [self update:nil tabBar:nil statusBar:nil fullscreen:nil]; + [self update:nil tabBar:nil statusBar:nil sideMenu:nil fullscreen:nil]; } - (void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation { @@ -286,7 +288,7 @@ if (exclude != nil) { for (UICompositeViewDescription *description in exclude) { if ([key isEqualToString:description.content] || [key isEqualToString:description.statusBar] || - [key isEqualToString:description.tabBar]) { + [key isEqualToString:description.tabBar] || [key isEqualToString:description.sideMenu]) { remove = false; break; } @@ -370,11 +372,13 @@ - (void)update:(UICompositeViewDescription *)description tabBar:(NSNumber *)tabBar statusBar:(NSNumber *)statusBar + sideMenu:(NSNumber *)sideMenu fullscreen:(NSNumber *)fullscreen { UIViewController *oldContentViewController = self.contentViewController; UIViewController *oldStatusBarViewController = self.statusBarViewController; UIViewController *oldTabBarViewController = self.tabBarViewController; + UIViewController *oldSideMenuViewController = self.sideMenuViewController; // Copy view description UICompositeViewDescription *oldViewDescription = nil; @@ -398,11 +402,18 @@ [self.tabBarView.layer removeAnimationForKey:@"transition"]; [self.tabBarView.layer addAnimation:self.viewTransition forKey:@"transition"]; } + if (oldViewDescription.sideMenu != currentViewDescription.sideMenu || + oldViewDescription.sideMenuEnabled != currentViewDescription.sideMenuEnabled || + [self.sideMenuView.layer animationForKey:@"transition"] != nil) { + [self.sideMenuView.layer removeAnimationForKey:@"transition"]; + [self.sideMenuView.layer addAnimation:self.viewTransition forKey:@"transition"]; + } } UIViewController *newContentViewController = [self getCachedController:description.content]; UIViewController *newStatusBarViewController = [self getCachedController:description.statusBar]; UIViewController *newTabBarViewController = [self getCachedController:description.tabBar]; + UIViewController *newSideMenuViewController = [self getCachedController:description.sideMenu]; [UICompositeView removeSubView:oldContentViewController]; if (oldTabBarViewController != nil && oldTabBarViewController != newTabBarViewController) { @@ -411,10 +422,14 @@ if (oldStatusBarViewController != nil && oldStatusBarViewController != newStatusBarViewController) { [UICompositeView removeSubView:oldStatusBarViewController]; } + if (oldSideMenuViewController != nil && oldSideMenuViewController != newSideMenuViewController) { + [UICompositeView removeSubView:oldSideMenuViewController]; + } self.statusBarViewController = newStatusBarViewController; self.contentViewController = newContentViewController; self.tabBarViewController = newTabBarViewController; + self.sideMenuViewController = newSideMenuViewController; // Update rotation UIInterfaceOrientation correctOrientation = [self @@ -441,11 +456,11 @@ [self.tabBarViewController willAnimateRotationToInterfaceOrientation:correctOrientation duration:0]; [self.tabBarViewController didRotateFromInterfaceOrientation:oldOrientation]; } - if (oldStatusBarViewController != newStatusBarViewController) { - UIInterfaceOrientation oldOrientation = self.statusBarViewController.interfaceOrientation; - [self.statusBarViewController willRotateToInterfaceOrientation:correctOrientation duration:0]; - [self.statusBarViewController willAnimateRotationToInterfaceOrientation:correctOrientation duration:0]; - [self.statusBarViewController didRotateFromInterfaceOrientation:oldOrientation]; + if (oldSideMenuViewController != newSideMenuViewController) { + UIInterfaceOrientation oldOrientation = self.sideMenuViewController.interfaceOrientation; + [self.sideMenuViewController willRotateToInterfaceOrientation:correctOrientation duration:0]; + [self.sideMenuViewController willAnimateRotationToInterfaceOrientation:correctOrientation duration:0]; + [self.sideMenuViewController didRotateFromInterfaceOrientation:oldOrientation]; } } } else { @@ -472,6 +487,14 @@ } } + if (sideMenu != nil) { + if (currentViewDescription.sideMenuEnabled != [sideMenu boolValue]) { + currentViewDescription.sideMenuEnabled = [sideMenu boolValue]; + } else { + sideMenu = nil; // No change = No Update + } + } + if (fullscreen != nil) { if (currentViewDescription.fullscreen != [fullscreen boolValue]) { currentViewDescription.fullscreen = [fullscreen boolValue]; @@ -486,7 +509,7 @@ } // Start animation - if (tabBar != nil || statusBar != nil || fullscreen != nil) { + if (tabBar != nil || statusBar != nil || sideMenu != nil || fullscreen != nil) { [UIView beginAnimations:@"resize" context:nil]; [UIView setAnimationDuration:0.35]; } @@ -503,7 +526,6 @@ if (self.statusBarViewController != nil && currentViewDescription.statusBarEnabled) { contentFrame.origin.y = origin + statusBarFrame.size.height; statusBarFrame.origin.y = origin; - origin = statusBarFrame.size.height; } else { contentFrame.origin.y = origin; statusBarFrame.origin.y = origin - statusBarFrame.size.height; @@ -535,30 +557,41 @@ } if (currentViewDescription.fullscreen) { - contentFrame.origin.y = origin; + // contentFrame.origin.y = origin; contentFrame.size.height = viewFrame.size.height - contentFrame.origin.y; } - // Set frames - [self.contentView setFrame:contentFrame]; - [self.contentViewController.view setFrame:[self.contentView bounds]]; - [self.tabBarView setFrame:tabFrame]; - CGRect frame = [self.tabBarViewController.view frame]; - frame.size.width = [self.tabBarView bounds].size.width; - [self.tabBarViewController.view setFrame:frame]; - [self.statusBarView setFrame:statusBarFrame]; - frame = [self.statusBarViewController.view frame]; - frame.size.width = [self.statusBarView bounds].size.width; - [self.statusBarViewController.view setFrame:frame]; - + // Resize SideMenu CGRect sideMenuFrame = contentFrame; - contentFrame.origin.x = (self.sideMenuView.hidden ? -contentFrame.size.width : 0); sideMenuFrame.size.height += tabFrame.size.height; + if (!currentViewDescription.sideMenuEnabled) { + sideMenuFrame.origin.x = -contentFrame.size.width; + } + + // Set frames + + // 1. content view + self.contentView.frame = contentFrame; + self.contentViewController.view.frame = self.contentView.bounds; + + // 2. tab bar + self.tabBarView.frame = tabFrame; + CGRect frame = self.tabBarViewController.view.frame; + frame.size.width = self.tabBarView.bounds.size.width; + self.tabBarViewController.view.frame = frame; + + // 3. status bar + self.statusBarView.frame = statusBarFrame; + frame = self.statusBarViewController.view.frame; + frame.size.width = self.statusBarView.bounds.size.width; + self.statusBarViewController.view.frame = frame; + + // 4. side menu self.sideMenuView.frame = sideMenuFrame; - _sideMenuViewController.view.frame = [self.sideMenuView bounds]; + self.sideMenuViewController.view.frame = self.sideMenuView.bounds; // Commit animation - if (tabBar != nil || statusBar != nil || fullscreen != nil) { + if (tabBar != nil || statusBar != nil || sideMenu != nil || fullscreen != nil) { [UIView commitAnimations]; } @@ -571,6 +604,9 @@ if (oldStatusBarViewController == nil || oldStatusBarViewController != self.statusBarViewController) { [UICompositeView addSubView:self.statusBarViewController view:self.statusBarView]; } + if (oldSideMenuViewController == nil || oldSideMenuViewController != self.sideMenuViewController) { + [UICompositeView addSubView:self.sideMenuViewController view:self.sideMenuView]; + } } // Dealloc old view description @@ -578,61 +614,62 @@ - (void)changeView:(UICompositeViewDescription *)description { [self view]; // Force view load - [self update:description tabBar:nil statusBar:nil fullscreen:nil]; + [self update:description tabBar:nil statusBar:nil sideMenu:nil fullscreen:nil]; } - (void)setFullscreen:(BOOL)enabled { - [self update:nil tabBar:nil statusBar:nil fullscreen:[NSNumber numberWithBool:enabled]]; + [self update:nil tabBar:nil statusBar:nil sideMenu:nil fullscreen:[NSNumber numberWithBool:enabled]]; } - (void)hideTabBar:(BOOL)hidden { - [self update:nil tabBar:[NSNumber numberWithBool:!hidden] statusBar:nil fullscreen:nil]; + [self update:nil tabBar:[NSNumber numberWithBool:!hidden] statusBar:nil sideMenu:nil fullscreen:nil]; } - (void)hideStatusBar:(BOOL)hidden { - [self update:nil tabBar:nil statusBar:[NSNumber numberWithBool:!hidden] fullscreen:nil]; + [self update:nil tabBar:nil statusBar:[NSNumber numberWithBool:!hidden] sideMenu:nil fullscreen:nil]; } - (void)hideSideMenu:(BOOL)hidden { - [self hideSideMenu:hidden - animated:[[LinphoneManager instance] lpConfigBoolForKey:@"animations_preference" withDefault:YES]]; + [self update:nil tabBar:nil statusBar:nil sideMenu:[NSNumber numberWithBool:!hidden] fullscreen:nil]; + // [self hideSideMenu:hidden + // animated:[[LinphoneManager instance] lpConfigBoolForKey:@"animations_preference" withDefault:YES]]; } -- (void)hideSideMenu:(BOOL)hidden animated:(BOOL)animated { - LOGI(@"%s side menu %s animation", hidden ? "Closing" : "Opening", animated ? "with" : "without"); - - // resign keyboard, if any - [LinphoneUtils findAndResignFirstResponder:self.view]; - - CGRect d = self.sideMenuView.frame; - d.origin.x = hidden ? 0 : -d.size.width; - self.sideMenuView.frame = d; - d.origin.x = hidden ? -d.size.width : 0; - - if (animated) { - self.sideMenuView.hidden = NO; - [UIView animateWithDuration:0.3 - animations:^{ - self.sideMenuView.frame = d; - } - completion:^(BOOL finished) { - self.sideMenuView.hidden = hidden; - if (hidden) { - [self.sideMenuViewController viewWillDisappear:animated]; - } else { - [self.sideMenuViewController viewWillAppear:animated]; - } - }]; - } else { - self.sideMenuView.frame = d; - self.sideMenuView.hidden = hidden; - if (hidden) { - [self.sideMenuViewController viewWillDisappear:animated]; - } else { - [self.sideMenuViewController viewWillAppear:animated]; - } - } -} +//- (void)hideSideMenu:(BOOL)hidden animated:(BOOL)animated { +// LOGI(@"%s side menu %s animation", hidden ? "Closing" : "Opening", animated ? "with" : "without"); +// +// // resign keyboard, if any +// [LinphoneUtils findAndResignFirstResponder:self.view]; +// +// CGRect d = self.sideMenuView.frame; +// d.origin.x = hidden ? 0 : -d.size.width; +// self.sideMenuView.frame = d; +// d.origin.x = hidden ? -d.size.width : 0; +// +// if (animated) { +// self.sideMenuView.hidden = NO; +// [UIView animateWithDuration:0.3 +// animations:^{ +// self.sideMenuView.frame = d; +// } +// completion:^(BOOL finished) { +// self.sideMenuView.hidden = hidden; +// if (hidden) { +// [self.sideMenuViewController viewWillDisappear:animated]; +// } else { +// [self.sideMenuViewController viewWillAppear:animated]; +// } +// }]; +// } else { +// self.sideMenuView.frame = d; +// self.sideMenuView.hidden = hidden; +// if (hidden) { +// [self.sideMenuViewController viewWillDisappear:animated]; +// } else { +// [self.sideMenuViewController viewWillAppear:animated]; +// } +// } +//} - (UIViewController *)getCurrentViewController { return self.contentViewController; diff --git a/Classes/PhoneMainView.h b/Classes/PhoneMainView.h index 5c44e288b..7caa75e7b 100644 --- a/Classes/PhoneMainView.h +++ b/Classes/PhoneMainView.h @@ -38,6 +38,7 @@ #import "SettingsView.h" #import "SideMenuView.h" #import "AssistantView.h" +#import "CallSideMenuView.h" //#import "ChatConversationCreateView.h" #import "UIConfirmationDialog.h" #import "DTAlertView.h" diff --git a/Classes/SettingsView.m b/Classes/SettingsView.m index 576a9b3cb..44314771d 100644 --- a/Classes/SettingsView.m +++ b/Classes/SettingsView.m @@ -353,6 +353,7 @@ static UICompositeViewDescription *compositeDescription = nil; compositeDescription = [[UICompositeViewDescription alloc] init:self.class statusBar:StatusBarView.class tabBar:TabBarView.class + sideMenu:SideMenuView.class fullscreen:false landscapeMode:LinphoneManager.runningOnIpad portraitMode:true]; diff --git a/Classes/SideMenuView.xib b/Classes/SideMenuView.xib index 20169cff9..96584d258 100644 --- a/Classes/SideMenuView.xib +++ b/Classes/SideMenuView.xib @@ -82,6 +82,7 @@ + diff --git a/linphone.xcodeproj/project.pbxproj b/linphone.xcodeproj/project.pbxproj index 354ec0e82..ba17882b3 100755 --- a/linphone.xcodeproj/project.pbxproj +++ b/linphone.xcodeproj/project.pbxproj @@ -312,6 +312,8 @@ 6352A5581BDFCF2C00594C1C /* valid_disabled.png in Resources */ = {isa = PBXBuildFile; fileRef = 6352A4841BDFCF2C00594C1C /* valid_disabled.png */; }; 6352A5591BDFCF2C00594C1C /* voicemail.png in Resources */ = {isa = PBXBuildFile; fileRef = 6352A4851BDFCF2C00594C1C /* voicemail.png */; }; 6352A55A1BDFCF2C00594C1C /* waiting_time.png in Resources */ = {isa = PBXBuildFile; fileRef = 6352A4861BDFCF2C00594C1C /* waiting_time.png */; }; + 6352A5751BE0D4B800594C1C /* CallSideMenuView.m in Sources */ = {isa = PBXBuildFile; fileRef = 6352A5731BE0D4B800594C1C /* CallSideMenuView.m */; }; + 6352A5761BE0D4B800594C1C /* CallSideMenuView.xib in Resources */ = {isa = PBXBuildFile; fileRef = 6352A5741BE0D4B800594C1C /* CallSideMenuView.xib */; }; 635775251B6673EC00C8B704 /* HistoryDetailsTableView.m in Sources */ = {isa = PBXBuildFile; fileRef = 635775241B6673EC00C8B704 /* HistoryDetailsTableView.m */; }; 636316D11A1DEBCB0009B839 /* AboutView.xib in Resources */ = {isa = PBXBuildFile; fileRef = 636316D31A1DEBCB0009B839 /* AboutView.xib */; }; 636316D41A1DEC650009B839 /* SettingsView.xib in Resources */ = {isa = PBXBuildFile; fileRef = 636316D61A1DEC650009B839 /* SettingsView.xib */; }; @@ -975,6 +977,9 @@ 6352A4841BDFCF2C00594C1C /* valid_disabled.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = valid_disabled.png; sourceTree = ""; }; 6352A4851BDFCF2C00594C1C /* voicemail.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = voicemail.png; sourceTree = ""; }; 6352A4861BDFCF2C00594C1C /* waiting_time.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = waiting_time.png; sourceTree = ""; }; + 6352A5721BE0D4B800594C1C /* CallSideMenuView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CallSideMenuView.h; sourceTree = ""; }; + 6352A5731BE0D4B800594C1C /* CallSideMenuView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CallSideMenuView.m; sourceTree = ""; }; + 6352A5741BE0D4B800594C1C /* CallSideMenuView.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = CallSideMenuView.xib; sourceTree = ""; }; 635775231B6673EC00C8B704 /* HistoryDetailsTableView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HistoryDetailsTableView.h; sourceTree = ""; }; 635775241B6673EC00C8B704 /* HistoryDetailsTableView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = HistoryDetailsTableView.m; sourceTree = ""; }; 636316D21A1DEBCB0009B839 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/AboutView.xib; sourceTree = ""; }; @@ -1447,6 +1452,9 @@ 634610101B6140A500548952 /* CallOutgoingView.xib */, D31AAF5C159B3919002C6B02 /* CallPausedTableView.h */, D31AAF5D159B3919002C6B02 /* CallPausedTableView.m */, + 6352A5721BE0D4B800594C1C /* CallSideMenuView.h */, + 6352A5731BE0D4B800594C1C /* CallSideMenuView.m */, + 6352A5741BE0D4B800594C1C /* CallSideMenuView.xib */, D3F83EE91582021700336684 /* CallView.h */, D3F83EEA1582021700336684 /* CallView.m */, D381881C15FE3FCA00C3EDCA /* CallView.xib */, @@ -2494,6 +2502,7 @@ 6352A4C01BDFCF2C00594C1C /* chat_send_over.png in Resources */, 6352A4E41BDFCF2C00594C1C /* delete_field_over.png in Resources */, 6352A5481BDFCF2C00594C1C /* status_available.png in Resources */, + 6352A5761BE0D4B800594C1C /* CallSideMenuView.xib in Resources */, 6352A51D1BDFCF2C00594C1C /* numpad_8_over.png in Resources */, 6352A52A1BDFCF2C00594C1C /* options_start_conference_disabled.png in Resources */, 6352A5251BDFCF2C00594C1C /* options_add_call_disabled.png in Resources */, @@ -2819,6 +2828,7 @@ 2248E90E12F7E4CF00220D9C /* UIDigitButton.m in Sources */, 633756391B67BAF400E21BAD /* SideMenuTableView.m in Sources */, 2214EB7A12F846B1002A5394 /* UICallButton.m in Sources */, + 6352A5751BE0D4B800594C1C /* CallSideMenuView.m in Sources */, 2214EB8912F84EBB002A5394 /* UIHangUpButton.m in Sources */, 630CF5571AF7CE1500539F7A /* UITextField+DoneButton.m in Sources */, 2214EBF312F86360002A5394 /* UIMicroButton.m in Sources */,