Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[TIMOB-15402] Let popover proxy manage windows #4784

Merged
merged 3 commits into from
Oct 17, 2013
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
22 changes: 20 additions & 2 deletions apidoc/Titanium/UI/iPad/Popover.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,9 @@ description: |
the existing content in a special type of window. The popover remains visible until the user
taps outside of the popover window or it is explicitly dismissed.

Do not add top-level view containers, such as a `Window` or `TabGroup`, to a popover.
Adding top-level view containers may have unintended side effects.
Do not add top-level view containers, such as a `SplitWindow` or `TabGroup`, to a popover.
Adding top-level view containers may have unintended side effects. See the [contentView](Titanium.UI.iPad.Popover.contentView)
property for more information.

![popover](http://img.skitch.com/20100406-pmssjk1a3a65s6ui8qnbqi59c4.png)
extends: Titanium.UI.View
Expand Down Expand Up @@ -65,16 +66,33 @@ properties:
type: Number
permission: read-only

- name: contentView
summary: The View to use for popover content instead of the popover. Must be set before calling `show` method.
description: |
This is now the preferred way to set the popover content. This can be set to any <Titanium.UI.View> object.
This property also supports the <Titanium.UI.Window> and <Titanium.UI.iOS.NavigationWindow> objects.
This property does not support the <Titanium.UI.iPad.SplitWindow> or <Titanium.UI.TabGroup> objects.
When this property is set to a valid object, the popover ** does not include the navigation controller**.
Set this to a <Titanium.UI.iOS.NavigationWindow> object to display and manage the navigation controller.
type: Titanium.UI.View
since: 3.2.0

- name: leftNavButton
summary: Left button in the navigation area of the popover.
description: |
Ignored when [contentView](Titanium.UI.iPad.Popover.contentView) is set.
type: Object

- name: rightNavButton
summary: Right button in the navigation area of the popover.
description: |
Ignored when [contentView](Titanium.UI.iPad.Popover.contentView) is set.
type: Object

- name: title
summary: Title of the navigation area of the popover.
description: |
Ignored when [contentView](Titanium.UI.iPad.Popover.contentView) is set.
type: String

examples:
Expand Down
21 changes: 10 additions & 11 deletions iphone/Classes/TiUIiPadPopoverProxy.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,24 +14,23 @@
//If the view had the logic, you get some nasty dependency loops.
@interface TiUIiPadPopoverProxy : TiViewProxy<UIPopoverControllerDelegate> {
@private
UIPopoverController *popoverController;
UINavigationController *navigationController;
TiViewController *viewController;
UIPopoverController *popoverController;
UINavigationController *navigationController;
UIViewController *viewController;
TiViewProxy *contentViewProxy;
//We need to hold onto this information for whenever the status bar rotates.
TiViewProxy *popoverView;
CGRect popoverRect;
BOOL animated;
UIPopoverArrowDirection directions;

//We need to hold onto this information for whenever the status bar rotates.
TiViewProxy *popoverView;
CGRect popoverRect;
BOOL animated;
UIPopoverArrowDirection directions;

BOOL isShowing;
BOOL isShowing;
BOOL isDismissing;
NSCondition* closingCondition;
}

//Because the Popover isn't meant to be placed in anywhere specific,
@property(nonatomic,readonly) UIPopoverController *popoverController;
@property(nonatomic,readwrite,retain) TiViewController *viewController;


@property(nonatomic,readwrite,retain) TiViewProxy *popoverView;
Expand Down
151 changes: 123 additions & 28 deletions iphone/Classes/TiUIiPadPopoverProxy.m
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,26 @@
#import "TiUIiPadPopoverProxy.h"
#import "TiUIiPadPopover.h"
#import "TiUtils.h"
#import "TiWindowProxy.h"
#import <libkern/OSAtomic.h>

TiUIiPadPopoverProxy * currentlyDisplaying = nil;

@implementation TiUIiPadPopoverProxy
@synthesize viewController, popoverView;
@synthesize popoverView;

static NSArray* popoverSequence;

#pragma mark Internal

-(NSArray *)keySequence
{
if (popoverSequence == nil)
{
popoverSequence = [[NSArray arrayWithObjects:@"contentView",@"width",@"height",nil] retain];
}
return popoverSequence;
}
#pragma mark Setup

-(id)init
Expand All @@ -37,6 +50,7 @@ -(void)dealloc
RELEASE_TO_NIL(popoverController);
RELEASE_TO_NIL(popoverView);
RELEASE_TO_NIL(closingCondition);
RELEASE_TO_NIL(contentViewProxy);
[super dealloc];
}

Expand Down Expand Up @@ -82,8 +96,10 @@ -(CGSize)contentSize
CGSize tempSize = CGSizeMake(screenSize.height, screenSize.width);
screenSize = tempSize;
}

return SizeConstraintViewWithSizeAddingResizing([self layoutProperties], self, screenSize , NULL);
if (contentViewProxy != nil) {
return SizeConstraintViewWithSizeAddingResizing([contentViewProxy layoutProperties], contentViewProxy, screenSize , NULL);
}
return SizeConstraintViewWithSizeAddingResizing([self layoutProperties], self, screenSize , NULL);
}

-(UINavigationController *)navigationController
Expand All @@ -99,51 +115,83 @@ -(UINavigationController *)navigationController
-(void)updateContentSize
{
CGSize newSize = [self contentSize];
[[self viewController] setContentSizeForViewInPopover:newSize];
[self reposition];
if ([TiUtils isIOS7OrGreater]) {
[[self viewController] setPreferredContentSize:newSize];
} else {
[[self viewController] setContentSizeForViewInPopover:newSize];
}
if (contentViewProxy != nil) {
[contentViewProxy reposition];
} else {
[self reposition];
}
}



#pragma mark Accessors
-(TiViewController *)viewController
-(UIViewController *)viewController
{
if (viewController == nil)
{
viewController = [[TiViewController alloc] initWithViewProxy:self];
[TiUtils configureController:viewController withObject:nil];
}
return viewController;
if (viewController == nil) {
if (contentViewProxy != nil) {
if ([contentViewProxy isKindOfClass:[TiWindowProxy class]]) {
[(TiWindowProxy*)contentViewProxy setIsManaged:YES];
viewController = [[(TiWindowProxy*)contentViewProxy hostingController] retain];
} else {
viewController = [[TiViewController alloc] initWithViewProxy:contentViewProxy];
}
} else {
viewController = [[TiViewController alloc] initWithViewProxy:self];
}
}
return viewController;
}

-(UIPopoverController *)popoverController
{
if (popoverController == nil)
{
popoverController = [[UIPopoverController alloc] initWithContentViewController:[self navigationController]];
[popoverController setDelegate:self];
[self refreshTitleBarWithObject:nil];
[self updateContentSize];
}
return popoverController;
if (popoverController == nil) {
if (contentViewProxy != nil) {
popoverController = [[UIPopoverController alloc] initWithContentViewController:[self viewController]];
} else {
popoverController = [[UIPopoverController alloc] initWithContentViewController:[self navigationController]];
[self refreshTitleBarWithObject:nil];
}
[popoverController setDelegate:self];
[self updateContentSize];
}
return popoverController;
}

#pragma mark Public-facing accessors

-(void)setRightNavButton:(id)item withObject:(id)properties
{
if (contentViewProxy != nil) {
DebugLog(@"[ERROR] Popover is using the contentView to display content. Ignoring.");
return;
}
ENSURE_SINGLE_ARG_OR_NIL(item,TiViewProxy);
[self replaceValue:item forKey:@"rightNavButton" notification:NO];
[self refreshTitleBarWithObject:properties];
}

-(void)setLeftNavButton:(id)item withObject:(id)properties
{
if (contentViewProxy != nil) {
DebugLog(@"[ERROR] Popover is using the contentView to display content. Ignoring.");
return;
}
ENSURE_SINGLE_ARG_OR_NIL(item,TiViewProxy);
[self replaceValue:item forKey:@"leftNavButton" notification:NO];
[self refreshTitleBarWithObject:properties];
}

-(void)setNavBarHidden:(id)item withObject:(id)properties
{
if (contentViewProxy != nil) {
DebugLog(@"[ERROR] Popover is using the contentView to display content. Ignoring.");
return;
}
[self replaceValue:item forKey:@"navBarHidden" notification:NO];
[self refreshTitleBarWithObject:properties];
}
Expand Down Expand Up @@ -182,13 +230,20 @@ -(void)hideNavBar:(NSArray*)args

-(void)setTitle:(id)item
{
if (contentViewProxy != nil) {
DebugLog(@"[ERROR] Popover is using the contentView to display content. Ignoring.");
}
[self replaceValue:item forKey:@"title" notification:NO];
[self refreshTitleBarWithObject:nil];
}

-(void)setWidth:(id)value
{
[super setWidth:value];
if (contentViewProxy != nil) {
[contentViewProxy setWidth:value];
} else {
[super setWidth:value];
}
if (popoverController != nil)
{
TiThreadPerformOnMainThread(^{[self updateContentSize];}, NO);
Expand All @@ -197,13 +252,32 @@ -(void)setWidth:(id)value

-(void)setHeight:(id)value
{
[super setHeight:value];
if (contentViewProxy != nil) {
[contentViewProxy setHeight:value];
} else {
[super setHeight:value];
}
if (popoverController != nil)
{
TiThreadPerformOnMainThread(^{[self updateContentSize];}, NO);
}
}

-(void)setContentView:(id)value
{
ENSURE_SINGLE_ARG(value, TiViewProxy);
if (isShowing) {
DebugLog(@"[ERROR] Changing contentView when the popover is showing is not supported");
return;
}
if (contentViewProxy != nil) {
RELEASE_TO_NIL(contentViewProxy);
}
contentViewProxy = [(TiViewProxy*) value retain];
[self replaceValue:contentViewProxy forKey:@"contentView" notification:NO];

}


-(void)show:(id)args
{
Expand Down Expand Up @@ -236,10 +310,23 @@ -(void)show:(id)args

TiThreadPerformOnMainThread(^{
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(updatePopover:) name:UIApplicationWillChangeStatusBarOrientationNotification object:nil];
[self windowWillOpen];
[self reposition];
[self updatePopoverNow];
[self windowDidOpen];
if (contentViewProxy != nil) {
if ([contentViewProxy isKindOfClass:[TiWindowProxy class]]) {
[(TiWindowProxy*)contentViewProxy open:nil];
[(TiWindowProxy*) contentViewProxy gainFocus];
[self updatePopoverNow];
} else {
[contentViewProxy windowWillOpen];
[contentViewProxy reposition];
[self updatePopoverNow];
[contentViewProxy windowDidOpen];
}
} else {
[self windowWillOpen];
[self reposition];
[self updatePopoverNow];
[self windowDidOpen];
}
},YES);

}
Expand Down Expand Up @@ -367,11 +454,19 @@ - (void)popoverControllerDidDismissPopover:(UIPopoverController *)thisPopoverCon
if (currentlyDisplaying == self) {
currentlyDisplaying = nil;
}
[self windowWillClose];
if (contentViewProxy != nil) {
[contentViewProxy windowWillClose];
} else {
[self windowWillClose];
}
isShowing = NO;
[self fireEvent:@"hide" withObject:nil]; //Checking for listeners are done by fireEvent anyways.
[[NSNotificationCenter defaultCenter] removeObserver:self name:UIApplicationWillChangeStatusBarOrientationNotification object:nil];
[self windowDidClose];
if (contentViewProxy != nil) {
[contentViewProxy windowDidClose];
} else {
[self windowDidClose];
}
[self forgetSelf];
RELEASE_TO_NIL(viewController);
RELEASE_TO_NIL_AUTORELEASE(popoverController);
Expand Down
4 changes: 2 additions & 2 deletions iphone/Classes/TiWindowProxy.m
Original file line number Diff line number Diff line change
Expand Up @@ -182,7 +182,7 @@ -(void)open:(id)args

opening = YES;

isModal = (tab == nil) ? [self argOrWindowProperty:@"modal" args:args] : NO;
isModal = (tab == nil && !self.isManaged) ? [self argOrWindowProperty:@"modal" args:args] : NO;

if ([self argOrWindowProperty:@"fullscreen" args:args]) {
hidesStatusBar = YES;
Expand Down Expand Up @@ -397,7 +397,7 @@ -(void)resignFocus
-(UIViewController*)hostingController;
{
if (controller == nil) {
controller = [[[TiViewController alloc] initWithViewProxy:self] retain];
controller = [[TiViewController alloc] initWithViewProxy:self];
}
return controller;
}
Expand Down