Call: add stats side menu

This commit is contained in:
Gautier Pelloux-Prayer 2015-10-28 14:21:43 +01:00
parent 28bd683b9b
commit 6d602049b3
28 changed files with 394 additions and 102 deletions

View file

@ -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];

View file

@ -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];

View file

@ -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];

View file

@ -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];

View file

@ -0,0 +1,20 @@
//
// SideMenuViewController.h
// linphone
//
// Created by Gautier Pelloux-Prayer on 28/07/15.
//
//
#import <UIKit/UIKit.h>
#import "SideMenuTableView.h"
#import "PhoneMainView.h"
@interface CallSideMenuView : UIViewController
@property(weak, nonatomic) IBOutlet UILabel *statsLabel;
- (IBAction)onLateralSwipe:(id)sender;
@end

147
Classes/CallSideMenuView.m Normal file
View file

@ -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

View file

@ -0,0 +1,55 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="7706" systemVersion="14F1021" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none">
<dependencies>
<deployment identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="7703"/>
</dependencies>
<objects>
<placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner" customClass="CallSideMenuView">
<connections>
<outlet property="statsLabel" destination="ZYY-EM-M2s" id="Syl-sZ-upy"/>
<outlet property="view" destination="YEG-7O-7jE" id="VGG-cE-thT"/>
</connections>
</placeholder>
<placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
<view clearsContextBeforeDrawing="NO" contentMode="scaleToFill" id="i5M-Pr-FkT">
<rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<view clearsContextBeforeDrawing="NO" contentMode="scaleToFill" id="YEG-7O-7jE">
<rect key="frame" x="0.0" y="42" width="375" height="625"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<label opaque="NO" userInteractionEnabled="NO" alpha="0.69999999999999973" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" textAlignment="center" lineBreakMode="tailTruncation" numberOfLines="30" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="ZYY-EM-M2s" userLabel="statsLabel">
<rect key="frame" x="0.0" y="0.0" width="300" height="625"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" flexibleMinY="YES" heightSizable="YES" flexibleMaxY="YES"/>
<color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
<string key="text">Audio: upr
Video: down</string>
<fontDescription key="fontDescription" type="system" pointSize="17"/>
<color key="textColor" cocoaTouchSystemColor="darkTextColor"/>
<nil key="highlightedColor"/>
</label>
</subviews>
<gestureRecognizers/>
<connections>
<outletCollection property="gestureRecognizers" destination="EB5-NY-DqU" appends="YES" id="Bz9-rW-UqV"/>
</connections>
</view>
</subviews>
<color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="calibratedWhite"/>
<simulatedScreenMetrics key="simulatedDestinationMetrics" type="retina47"/>
<point key="canvasLocation" x="473.5" y="318.5"/>
</view>
<tapGestureRecognizer id="EB5-NY-DqU">
<connections>
<action selector="onLateralSwipe:" destination="-1" id="Li9-LU-Om1"/>
</connections>
</tapGestureRecognizer>
</objects>
<simulatedMetricsContainer key="defaultSimulatedMetrics">
<simulatedStatusBarMetrics key="statusBar"/>
<simulatedOrientationMetrics key="orientation"/>
<simulatedScreenMetrics key="destination" type="retina4"/>
</simulatedMetricsContainer>
</document>

View file

@ -25,6 +25,7 @@
#import <OpenGLES/EAGLDrawable.h>
#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];
}
}

View file

@ -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];

View file

@ -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];

View file

@ -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];

View file

@ -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];

View file

@ -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];

View file

@ -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];

View file

@ -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];

View file

@ -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];

View file

@ -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];

View file

@ -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];

View file

@ -7,7 +7,7 @@
<objects>
<placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner" customClass="StatusBarView">
<connections>
<outlet property="callQualityImage" destination="13" id="16"/>
<outlet property="callQualityButton" destination="SKk-s0-5HE" id="22M-FN-kRs"/>
<outlet property="callSecurityButton" destination="27" id="29"/>
<outlet property="incallView" destination="0Vp-VF-wmX" id="mLI-RY-bfW"/>
<outlet property="outcallView" destination="lfO-I4-PXi" id="04e-SG-ViY"/>
@ -30,11 +30,6 @@
<rect key="frame" x="0.0" y="0.0" width="360" height="42"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<imageView hidden="YES" userInteractionEnabled="NO" tag="4" contentMode="center" image="call_quality_indicator_4.png" id="13" userLabel="callQualityImage">
<rect key="frame" x="0.0" y="0.0" width="40" height="40"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<accessibility key="accessibilityConfiguration" label="Call quality"/>
</imageView>
<button opaque="NO" tag="6" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" adjustsImageWhenHighlighted="NO" adjustsImageWhenDisabled="NO" lineBreakMode="middleTruncation" id="27" userLabel="callSecurityButton">
<rect key="frame" x="332" y="7" width="24" height="25"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMaxY="YES"/>
@ -53,6 +48,16 @@
<action selector="onSecurityClick:" destination="-1" eventType="touchUpInside" id="bdh-tU-zPP"/>
</connections>
</button>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" id="SKk-s0-5HE" userLabel="callQualityButton">
<rect key="frame" x="0.0" y="0.0" width="40" height="40"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<state key="normal" image="menu.png">
<color key="titleShadowColor" white="0.5" alpha="1" colorSpace="calibratedWhite"/>
</state>
<connections>
<action selector="onSideMenuClick:" destination="-1" eventType="touchUpInside" id="iOC-wy-MPP"/>
</connections>
</button>
</subviews>
</view>
<view contentMode="scaleToFill" id="lfO-I4-PXi" userLabel="outcallView">
@ -98,7 +103,6 @@
</view>
</objects>
<resources>
<image name="call_quality_indicator_4.png" width="19" height="19"/>
<image name="color_A.png" width="2" height="2"/>
<image name="led_disconnected.png" width="11" height="11"/>
<image name="menu.png" width="19" height="18"/>

View file

@ -1,6 +1,7 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="7706" systemVersion="14F1021" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none">
<dependencies>
<deployment identifier="iOS"/>
<development version="6000" identifier="xcode"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="7703"/>
</dependencies>
@ -40,15 +41,15 @@
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMinY="YES"/>
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="calibratedWhite"/>
</view>
<view hidden="YES" clearsContextBeforeDrawing="NO" contentMode="scaleToFill" id="26" userLabel="sideMenuView">
<view clearsContextBeforeDrawing="NO" contentMode="scaleToFill" id="26" userLabel="sideMenuView">
<rect key="frame" x="-375" y="42" width="375" height="625"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" flexibleMinY="YES" heightSizable="YES" flexibleMaxY="YES"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMinY="YES" heightSizable="YES"/>
</view>
</subviews>
<color key="backgroundColor" red="0.42048451599999997" green="1" blue="0.24647464969999999" alpha="1" colorSpace="calibratedRGB"/>
<nil key="simulatedStatusBarMetrics"/>
<simulatedScreenMetrics key="simulatedDestinationMetrics" type="retina47"/>
<point key="canvasLocation" x="-110.5" y="22.5"/>
<point key="canvasLocation" x="-96.5" y="-25.5"/>
</view>
<view contentMode="scaleToFill" id="20" userLabel="Landscape View">
<rect key="frame" x="0.0" y="0.0" width="667" height="375"/>

View file

@ -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;

View file

@ -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 {

View file

@ -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;

View file

@ -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;

View file

@ -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"

View file

@ -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];

View file

@ -82,6 +82,7 @@
</subviews>
<color key="backgroundColor" red="1" green="1" blue="0.0" alpha="1" colorSpace="calibratedRGB"/>
<simulatedScreenMetrics key="simulatedDestinationMetrics" type="retina47"/>
<point key="canvasLocation" x="322.5" y="209.5"/>
</view>
<tableViewController id="Yyh-z6-IGO" customClass="SideMenuTableView">
<simulatedStatusBarMetrics key="simulatedStatusBarMetrics"/>

View file

@ -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 = "<group>"; };
6352A4851BDFCF2C00594C1C /* voicemail.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = voicemail.png; sourceTree = "<group>"; };
6352A4861BDFCF2C00594C1C /* waiting_time.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = waiting_time.png; sourceTree = "<group>"; };
6352A5721BE0D4B800594C1C /* CallSideMenuView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CallSideMenuView.h; sourceTree = "<group>"; };
6352A5731BE0D4B800594C1C /* CallSideMenuView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CallSideMenuView.m; sourceTree = "<group>"; };
6352A5741BE0D4B800594C1C /* CallSideMenuView.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = CallSideMenuView.xib; sourceTree = "<group>"; };
635775231B6673EC00C8B704 /* HistoryDetailsTableView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HistoryDetailsTableView.h; sourceTree = "<group>"; };
635775241B6673EC00C8B704 /* HistoryDetailsTableView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = HistoryDetailsTableView.m; sourceTree = "<group>"; };
636316D21A1DEBCB0009B839 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/AboutView.xib; sourceTree = "<group>"; };
@ -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 */,