mirror of
https://github.com/cappuccino/cappuccino.git
synced 2026-09-24 11:20:42 +00:00
CPPopover tweaks:
- Added animationStyle (Lion/iOS) to CPPopover. iOS style does not zoom open, it just appears. - Tweaked the Lion animation a bit to be a bit less rushed and match Mac OS X timing better. - Fixed some typos.
This commit is contained in:
+27
-18
@@ -35,6 +35,8 @@ CPPopoverBehaviorApplicationDefined = 0;
|
||||
CPPopoverBehaviorTransient = 1;
|
||||
CPPopoverBehaviorSemitransient = 2;
|
||||
|
||||
CPPopoverAnimationStyleLion = 0;
|
||||
CPPopoverAnimationStyleIOS = 1;
|
||||
|
||||
var CPPopoverDelegate_popover_willShow_ = 1 << 0,
|
||||
CPPopoverDelegate_popover_didShow_ = 1 << 1,
|
||||
@@ -50,11 +52,14 @@ var CPPopoverDelegate_popover_willShow_ = 1 << 0,
|
||||
view relative to another one.
|
||||
|
||||
Delegate can implement:
|
||||
– popoverShouldClose:(CPPopover)aPopOver
|
||||
– popoverWillShow:(CPPopover)aPopOver
|
||||
– popoverDidShow:(CPPopover)aPopOver
|
||||
– popoverWillClose:(CPPopover)aPopOver
|
||||
– popoverDidClose:(CPPopover)aPopOver
|
||||
|
||||
@code
|
||||
– popoverShouldClose:(CPPopover)aPopOver
|
||||
– popoverWillShow:(CPPopover)aPopOver
|
||||
– popoverDidShow:(CPPopover)aPopOver
|
||||
– popoverWillClose:(CPPopover)aPopOver
|
||||
– popoverDidClose:(CPPopover)aPopOver
|
||||
@endcode
|
||||
*/
|
||||
@implementation CPPopover : CPResponder
|
||||
{
|
||||
@@ -62,6 +67,7 @@ var CPPopoverDelegate_popover_willShow_ = 1 << 0,
|
||||
@outlet id _delegate @accessors(getter=delegate);
|
||||
|
||||
BOOL _animates @accessors(property=animates);
|
||||
int _animationStyle @accessors(property=animationStyle);
|
||||
BOOL _shown @accessors(getter=shown);
|
||||
int _appearance @accessors(property=appearance);
|
||||
int _behavior @accessors(getter=behavior);
|
||||
@@ -85,6 +91,7 @@ var CPPopoverDelegate_popover_willShow_ = 1 << 0,
|
||||
if (self = [super init])
|
||||
{
|
||||
_animates = YES;
|
||||
_animationStyle = CPPopoverAnimationStyleLion;
|
||||
_appearance = CPPopoverAppearanceMinimal;
|
||||
_behavior = CPPopoverBehaviorApplicationDefined;
|
||||
_needsCompute = YES;
|
||||
@@ -101,9 +108,9 @@ var CPPopoverDelegate_popover_willShow_ = 1 << 0,
|
||||
/*!
|
||||
Returns the current rect of the popover
|
||||
|
||||
@return CPRect represeting the frame of the popover
|
||||
@return CGRect representing the frame of the popover
|
||||
*/
|
||||
- (CPRect)positioningRect
|
||||
- (CGRect)positioningRect
|
||||
{
|
||||
if (!_attachedWindow || ![_attachedWindow isVisible])
|
||||
return nil;
|
||||
@@ -113,7 +120,7 @@ var CPPopoverDelegate_popover_willShow_ = 1 << 0,
|
||||
/*! Sets the frame of the popover
|
||||
@param aRect the desired frame
|
||||
*/
|
||||
- (void)setPositioningRect:(CPRect)aRect
|
||||
- (void)setPositioningRect:(CGRect)aRect
|
||||
{
|
||||
if (!_attachedWindow || ![_attachedWindow isVisible])
|
||||
return;
|
||||
@@ -123,9 +130,9 @@ var CPPopoverDelegate_popover_willShow_ = 1 << 0,
|
||||
/*!
|
||||
Returns the size of the popover's view
|
||||
|
||||
@return CPSize represeting the size of the popover's view
|
||||
@return CGSize representing the size of the popover's view
|
||||
*/
|
||||
- (CPRect)contentSize
|
||||
- (CGSize)contentSize
|
||||
{
|
||||
if (!_attachedWindow || ![_attachedWindow isVisible])
|
||||
return nil;
|
||||
@@ -145,7 +152,7 @@ var CPPopoverDelegate_popover_willShow_ = 1 << 0,
|
||||
/*!
|
||||
Indicates if CPPopover is visible
|
||||
|
||||
@returns YES if visible
|
||||
@returns \c YES if visible
|
||||
*/
|
||||
- (BOOL)shown
|
||||
{
|
||||
@@ -155,11 +162,12 @@ var CPPopoverDelegate_popover_willShow_ = 1 << 0,
|
||||
}
|
||||
|
||||
/*!
|
||||
Set the behaviour of the CPPopover. It can be
|
||||
- CPPopoverBehaviorTransient: the popover will be close if another control outside the popover become the responder
|
||||
- CPPopoverBehaviorApplicationDefined: (DEFAULT) the application is responsible for closing the popover
|
||||
Set the behaviour of the CPPopover. It can be:
|
||||
|
||||
@param aBehaviour the desired behaviour
|
||||
- \c CPPopoverBehaviorTransient: the popover will be close if another control outside the popover become the responder
|
||||
- \c CPPopoverBehaviorApplicationDefined: (DEFAULT) the application is responsible for closing the popover
|
||||
|
||||
@param aBehaviour the desired behaviour
|
||||
*/
|
||||
- (void)setBehaviour:(int)aBehaviour
|
||||
{
|
||||
@@ -203,9 +211,9 @@ var CPPopoverDelegate_popover_willShow_ = 1 << 0,
|
||||
|
||||
@param positioningRect if set, the popover will be positionned to a random rect relative to the window
|
||||
@param positioningView if set, the popover will be positioned relative to this view
|
||||
@param preferredEdge: CPRectEdge representing the preferred positioning.
|
||||
@param preferredEdge: \c CPRectEdge representing the preferred positioning.
|
||||
*/
|
||||
- (void)showRelativeToRect:(CPRect)positioningRect ofView:(CPView)positioningView preferredEdge:(CPRectEdge)preferredEdge
|
||||
- (void)showRelativeToRect:(CGRect)positioningRect ofView:(CPView)positioningView preferredEdge:(CPRectEdge)preferredEdge
|
||||
{
|
||||
if (_implementedDelegateMethods & CPPopoverDelegate_popover_willShow_)
|
||||
[_delegate popoverWillShow:self];
|
||||
@@ -216,11 +224,12 @@ var CPPopoverDelegate_popover_willShow_ = 1 << 0,
|
||||
if (_needsCompute || !_attachedWindow)
|
||||
{
|
||||
var styleMask = (_behavior == CPPopoverBehaviorTransient) ? CPClosableOnBlurWindowMask : nil;
|
||||
_attachedWindow = [[_CPAttachedWindow alloc] initWithContentRect:CPRectMakeZero() styleMask:styleMask];
|
||||
_attachedWindow = [[_CPAttachedWindow alloc] initWithContentRect:CGRectMakeZero() styleMask:styleMask];
|
||||
}
|
||||
|
||||
[_attachedWindow setAppearance:_appearance];
|
||||
[_attachedWindow setAnimates:_animates];
|
||||
[_attachedWindow setAnimationStyle:_animationStyle];
|
||||
[_attachedWindow setDelegate:self];
|
||||
[_attachedWindow setMovableByWindowBackground:NO];
|
||||
[_attachedWindow setFrame:[_attachedWindow frameRectForContentRect:[[_contentViewController view] frame]]];
|
||||
|
||||
+63
-41
@@ -43,6 +43,7 @@ var _CPAttachedWindow_attachedWindowShouldClose_ = 1 << 0,
|
||||
@implementation _CPAttachedWindow : CPWindow
|
||||
{
|
||||
BOOL _animates @accessors(property=animates);
|
||||
int _animationStyle @accessors(property=animationStyle);
|
||||
id _targetView @accessors(property=targetView);
|
||||
int _appearance @accessors(getter=appearance);
|
||||
|
||||
@@ -126,7 +127,7 @@ var _CPAttachedWindow_attachedWindowShouldClose_ = 1 << 0,
|
||||
if (self = [super initWithContentRect:aFrame styleMask:aStyleMask])
|
||||
{
|
||||
_animates = YES;
|
||||
_animates = YES;
|
||||
_animationStyle = CPPopoverAnimationStyleLion;
|
||||
_animationDuration = 150;
|
||||
_closeOnBlur = (aStyleMask & CPClosableOnBlurWindowMask);
|
||||
_isClosed = NO;
|
||||
@@ -136,9 +137,9 @@ var _CPAttachedWindow_attachedWindowShouldClose_ = 1 << 0,
|
||||
[self setMovableByWindowBackground:YES];
|
||||
[self setHasShadow:NO];
|
||||
|
||||
_DOMElement.style.WebkitBackfaceVisibility = "hidden";
|
||||
_DOMElement.style.WebkitTransitionProperty = "-webkit-transform, opacity";
|
||||
_DOMElement.style.WebkitTransitionDuration = _animationDuration + "ms";
|
||||
_DOMElement.style.webkitBackfaceVisibility = "hidden";
|
||||
_DOMElement.style.webkitTransitionProperty = "-webkit-transform, opacity";
|
||||
_DOMElement.style.webkitTransitionDuration = _animationDuration + "ms";
|
||||
|
||||
[_windowView setNeedsDisplay:YES];
|
||||
}
|
||||
@@ -151,7 +152,7 @@ var _CPAttachedWindow_attachedWindowShouldClose_ = 1 << 0,
|
||||
|
||||
- (void)setAppearance:(int)anAppearance
|
||||
{
|
||||
if (_appearance == anAppearance)
|
||||
if (_appearance === anAppearance)
|
||||
return;
|
||||
|
||||
[_windowView setAppearance:anAppearance];
|
||||
@@ -159,7 +160,7 @@ var _CPAttachedWindow_attachedWindowShouldClose_ = 1 << 0,
|
||||
|
||||
- (void)setDelegate:(id)aDelegate
|
||||
{
|
||||
if (_delegate == aDelegate)
|
||||
if (_delegate === aDelegate)
|
||||
return;
|
||||
|
||||
_delegate = aDelegate;
|
||||
@@ -375,7 +376,7 @@ var _CPAttachedWindow_attachedWindowShouldClose_ = 1 << 0,
|
||||
}
|
||||
|
||||
/*!
|
||||
Position the _CPAttachedWindow to a random point
|
||||
Position the _CPAttachedWindow to a given point
|
||||
|
||||
@param aPoint the point where the _CPAttachedWindow will be attached
|
||||
*/
|
||||
@@ -385,7 +386,7 @@ var _CPAttachedWindow_attachedWindowShouldClose_ = 1 << 0,
|
||||
}
|
||||
|
||||
/*!
|
||||
Position the _CPAttachedWindow to a random point
|
||||
Position the _CPAttachedWindow to a given point
|
||||
|
||||
@param aPoint the point where the _CPAttachedWindow will be attached
|
||||
@param anEdge the prefered edge
|
||||
@@ -442,47 +443,63 @@ var _CPAttachedWindow_attachedWindowShouldClose_ = 1 << 0,
|
||||
{
|
||||
[super orderFront:aSender];
|
||||
|
||||
var tranformOrigin = "50% 100%";
|
||||
var transformOrigin = "50% 100%";
|
||||
|
||||
switch ([_windowView preferredEdge])
|
||||
if (_animationStyle === CPPopoverAnimationStyleLion)
|
||||
{
|
||||
case CPMaxYEdge:
|
||||
var posX = 50 + (([_windowView arrowOffsetX] * 100) / _frame.size.width);
|
||||
tranformOrigin = posX + "% 0%"; // 50 0
|
||||
break;
|
||||
case CPMinYEdge:
|
||||
var posX = 50 + (([_windowView arrowOffsetX] * 100) / _frame.size.width);
|
||||
tranformOrigin = posX + "% 100%"; // 50 100
|
||||
break;
|
||||
case CPMinXEdge:
|
||||
var posY = 50 + (([_windowView arrowOffsetY] * 100) / _frame.size.height);
|
||||
tranformOrigin = "100% " + posY + "%"; // 100 50
|
||||
break;
|
||||
case CPMaxXEdge:
|
||||
var posY = 50 + (([_windowView arrowOffsetY] * 100) / _frame.size.height);
|
||||
tranformOrigin = "0% "+ posY + "%"; // 0 50
|
||||
break;
|
||||
switch ([_windowView preferredEdge])
|
||||
{
|
||||
case CPMaxYEdge:
|
||||
var posX = 50 + (([_windowView arrowOffsetX] * 100) / _frame.size.width);
|
||||
transformOrigin = posX + "% 0%"; // 50 0
|
||||
break;
|
||||
case CPMinYEdge:
|
||||
var posX = 50 + (([_windowView arrowOffsetX] * 100) / _frame.size.width);
|
||||
transformOrigin = posX + "% 100%"; // 50 100
|
||||
break;
|
||||
case CPMinXEdge:
|
||||
var posY = 50 + (([_windowView arrowOffsetY] * 100) / _frame.size.height);
|
||||
transformOrigin = "100% " + posY + "%"; // 100 50
|
||||
break;
|
||||
case CPMaxXEdge:
|
||||
var posY = 50 + (([_windowView arrowOffsetY] * 100) / _frame.size.height);
|
||||
transformOrigin = "0% "+ posY + "%"; // 0 50
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// @TODO: implement for FF
|
||||
if (_animates && _shouldPerformAnimation && typeof(_DOMElement.style.WebkitTransform) != "undefined")
|
||||
if (_animates && _shouldPerformAnimation && typeof(_DOMElement.style.webkitTransform) != "undefined")
|
||||
{
|
||||
_DOMElement.style.opacity = 0;
|
||||
_DOMElement.style.WebkitTransform = "scale(0)";
|
||||
_DOMElement.style.WebkitTransformOrigin = tranformOrigin;
|
||||
|
||||
if (_animationStyle === CPPopoverAnimationStyleLion)
|
||||
{
|
||||
_DOMElement.style.webkitTransform = "scale(0)";
|
||||
_DOMElement.style.webkitTransformOrigin = transformOrigin;
|
||||
}
|
||||
|
||||
window.setTimeout(function()
|
||||
{
|
||||
_DOMElement.style.opacity = 1;
|
||||
_DOMElement.style.height = _frame.size.height + @"px";
|
||||
_DOMElement.style.width = _frame.size.width + @"px";
|
||||
_DOMElement.style.opacity = 1;
|
||||
_DOMElement.style.WebkitTransform = "scale(1.1)";
|
||||
var transitionEndFunction = function()
|
||||
|
||||
if (_animationStyle === CPPopoverAnimationStyleLion)
|
||||
{
|
||||
_DOMElement.style.WebkitTransform = "scale(1)";
|
||||
_DOMElement.removeEventListener("webkitTransitionEnd", transitionEndFunction, YES);
|
||||
};
|
||||
_DOMElement.addEventListener("webkitTransitionEnd", transitionEndFunction, YES);
|
||||
},0);
|
||||
_DOMElement.style.webkitTransform = "scale(1.1)";
|
||||
_DOMElement.style.webkitTransitionDuration = "250ms";
|
||||
_DOMElement.style.webkitTransitionTimingFunction = "ease-out";
|
||||
|
||||
var transitionEndFunction = function()
|
||||
{
|
||||
_DOMElement.style.webkitTransform = "scale(1)";
|
||||
_DOMElement.removeEventListener("webkitTransitionEnd", transitionEndFunction, YES);
|
||||
};
|
||||
|
||||
_DOMElement.addEventListener("webkitTransitionEnd", transitionEndFunction, YES);
|
||||
}
|
||||
}, 0);
|
||||
}
|
||||
|
||||
[[CPNotificationCenter defaultCenter] addObserver:self selector:@selector(_attachedWindowDidMove:) name:CPWindowDidMoveNotification object:self];
|
||||
@@ -492,20 +509,25 @@ var _CPAttachedWindow_attachedWindowShouldClose_ = 1 << 0,
|
||||
}
|
||||
|
||||
/*!
|
||||
Close the windo with animation
|
||||
Close the window with animation
|
||||
*/
|
||||
- (void)close
|
||||
{
|
||||
// set a close flag to avoid infinite loop
|
||||
_isClosed = YES;
|
||||
|
||||
if (_animates && typeof(_DOMElement.style.WebkitTransform) != "undefined")
|
||||
if (_animates && typeof(_DOMElement.style.webkitTransform) != "undefined")
|
||||
{
|
||||
_DOMElement.style.opacity = 0;
|
||||
var transitionEndFunction = function(){
|
||||
[super close];
|
||||
_DOMElement.style.webkitTransitionDuration = "250ms";
|
||||
_DOMElement.style.webkitTransitionTimingFunction = "linear";
|
||||
|
||||
var transitionEndFunction = function()
|
||||
{
|
||||
[super close];
|
||||
_DOMElement.removeEventListener("webkitTransitionEnd", transitionEndFunction, YES);
|
||||
};
|
||||
|
||||
_DOMElement.addEventListener("webkitTransitionEnd", transitionEndFunction, YES);
|
||||
}
|
||||
else
|
||||
|
||||
@@ -73,7 +73,12 @@
|
||||
[buttonAnimation addItemWithTitle:"No animation"];
|
||||
[contentView addSubview:buttonAnimation];
|
||||
|
||||
buttonBehaviour = [[CPPopUpButton alloc] initWithFrame:CPRectMake(430, 10, 130, 24)];
|
||||
buttonAnimationStyle = [[CPPopUpButton alloc] initWithFrame:CPRectMake(430, 10, 130, 24)];
|
||||
[buttonAnimationStyle addItemWithTitle:"Lion"];
|
||||
[buttonAnimationStyle addItemWithTitle:"iOS"];
|
||||
[contentView addSubview:buttonAnimationStyle];
|
||||
|
||||
buttonBehaviour = [[CPPopUpButton alloc] initWithFrame:CPRectMake(570, 10, 130, 24)];
|
||||
[buttonBehaviour addItemWithTitle:"Transient"];
|
||||
[buttonBehaviour addItemWithTitle:"Not managed"];
|
||||
[contentView addSubview:buttonBehaviour];
|
||||
@@ -121,17 +126,18 @@
|
||||
|
||||
[label setFont:[CPFont boldSystemFontOfSize:30.0]];
|
||||
[label setFrameOrigin:CPPointMake(0, 70)];
|
||||
[label setValue:(a == CPPopoverAppearanceHUD) ? [CPColor colorWithHexString:@"333"] : [CPColor colorWithHexString:@"fff"] forThemeAttribute:@"text-shadow-color"];
|
||||
[label setValue:(a === CPPopoverAppearanceHUD) ? [CPColor colorWithHexString:@"333"] : [CPColor colorWithHexString:@"fff"] forThemeAttribute:@"text-shadow-color"];
|
||||
[label setValue:CGSizeMake(0.0, 1.0) forThemeAttribute:@"text-shadow-offset"];
|
||||
[label setTextColor:(a == CPPopoverAppearanceHUD) ? [CPColor whiteColor] : [CPColor colorWithHexString:@"444"]];
|
||||
[label setTextColor:(a === CPPopoverAppearanceHUD) ? [CPColor whiteColor] : [CPColor colorWithHexString:@"444"]];
|
||||
[label setFrameSize:CPSizeMake([view frame].size.width, 50)];
|
||||
[label setAlignment:CPCenterTextAlignment];
|
||||
[view addSubview:label];
|
||||
|
||||
[viewC setView:view];
|
||||
[p setContentViewController:viewC];
|
||||
[p setAnimates:([buttonAnimation title] == @"With animation")];
|
||||
[p setBehaviour:([buttonBehaviour title] == @"Transient") ? CPPopoverBehaviorTransient : CPPopoverBehaviorApplicationDefined];
|
||||
[p setAnimates:([buttonAnimation title] === @"With animation")];
|
||||
[p setAnimationStyle:[buttonAnimationStyle title] === @"Lion" ? CPPopoverAnimationStyleLion : CPPopoverAnimationStyleIOS];
|
||||
[p setBehaviour:([buttonBehaviour title] === @"Transient") ? CPPopoverBehaviorTransient : CPPopoverBehaviorApplicationDefined];
|
||||
[p setAppearance:a];
|
||||
[p setDelegate:self];
|
||||
[p showRelativeToRect:nil ofView:sender preferredEdge:g];
|
||||
|
||||
Reference in New Issue
Block a user