blob: a835883833cc3a5282ce6e3edd04f2f204183080 [file] [log] [blame]
/*
* Copyright (C) 2010 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*/
#import "config.h"
#import "TextIndicatorWindow.h"
#if PLATFORM(MAC)
#import "GeometryUtilities.h"
#import "GraphicsContext.h"
#import "PathUtilities.h"
#import "TextIndicator.h"
#import "WebActionDisablingCALayerDelegate.h"
#import "WebTextIndicatorLayer.h"
#import <pal/spi/cg/CoreGraphicsSPI.h>
#import <pal/spi/cocoa/NSColorSPI.h>
#import <pal/spi/cocoa/QuartzCoreSPI.h>
@interface WebTextIndicatorView : NSView
@end
@implementation WebTextIndicatorView
- (BOOL)isFlipped
{
return YES;
}
@end
using namespace WebCore;
namespace WebCore {
TextIndicatorWindow::TextIndicatorWindow(NSView *targetView)
: m_targetView(targetView)
, m_temporaryTextIndicatorTimer(RunLoop::main(), this, &TextIndicatorWindow::startFadeOut)
{
}
TextIndicatorWindow::~TextIndicatorWindow()
{
clearTextIndicator(WebCore::TextIndicatorDismissalAnimation::FadeOut);
}
void TextIndicatorWindow::setAnimationProgress(float progress)
{
if (!m_textIndicator)
return;
[m_textIndicatorLayer setAnimationProgress:progress];
}
void TextIndicatorWindow::clearTextIndicator(WebCore::TextIndicatorDismissalAnimation animation)
{
RefPtr<TextIndicator> textIndicator = WTFMove(m_textIndicator);
if ([m_textIndicatorLayer isFadingOut])
return;
if (textIndicator && [m_textIndicatorLayer indicatorWantsManualAnimation:*textIndicator] && [m_textIndicatorLayer hasCompletedAnimation] && animation == WebCore::TextIndicatorDismissalAnimation::FadeOut) {
startFadeOut();
return;
}
closeWindow();
}
void TextIndicatorWindow::setTextIndicator(Ref<TextIndicator> textIndicator, CGRect textBoundingRectInScreenCoordinates, TextIndicatorLifetime lifetime)
{
if (m_textIndicator == textIndicator.ptr())
return;
closeWindow();
m_textIndicator = textIndicator.ptr();
CGFloat horizontalMargin = dropShadowBlurRadius * 2 + TextIndicator::defaultHorizontalMargin;
CGFloat verticalMargin = dropShadowBlurRadius * 2 + TextIndicator::defaultVerticalMargin;
if ([m_textIndicatorLayer indicatorWantsBounce:*m_textIndicator]) {
horizontalMargin = std::max(horizontalMargin, textBoundingRectInScreenCoordinates.size.width * (WebCore::midBounceScale - 1) + horizontalMargin);
verticalMargin = std::max(verticalMargin, textBoundingRectInScreenCoordinates.size.height * (WebCore::midBounceScale - 1) + verticalMargin);
}
horizontalMargin = CGCeiling(horizontalMargin);
verticalMargin = CGCeiling(verticalMargin);
CGRect contentRect = CGRectInset(textBoundingRectInScreenCoordinates, -horizontalMargin, -verticalMargin);
NSRect windowContentRect = [NSWindow contentRectForFrameRect:NSRectFromCGRect(contentRect) styleMask:NSWindowStyleMaskBorderless];
NSRect integralWindowContentRect = NSIntegralRect(windowContentRect);
NSPoint fractionalTextOffset = NSMakePoint(windowContentRect.origin.x - integralWindowContentRect.origin.x, windowContentRect.origin.y - integralWindowContentRect.origin.y);
m_textIndicatorWindow = adoptNS([[NSWindow alloc] initWithContentRect:integralWindowContentRect styleMask:NSWindowStyleMaskBorderless backing:NSBackingStoreBuffered defer:NO]);
[m_textIndicatorWindow setBackgroundColor:[NSColor clearColor]];
[m_textIndicatorWindow setOpaque:NO];
[m_textIndicatorWindow setIgnoresMouseEvents:YES];
NSRect frame = NSMakeRect(0, 0, [m_textIndicatorWindow frame].size.width, [m_textIndicatorWindow frame].size.height);
m_textIndicatorLayer = adoptNS([[WebTextIndicatorLayer alloc] initWithFrame:frame
textIndicator:*m_textIndicator margin:NSMakeSize(horizontalMargin, verticalMargin) offset:fractionalTextOffset]);
m_textIndicatorView = adoptNS([[WebTextIndicatorView alloc] initWithFrame:frame]);
[m_textIndicatorView setLayer:m_textIndicatorLayer.get()];
[m_textIndicatorView setWantsLayer:YES];
[m_textIndicatorWindow setContentView:m_textIndicatorView.get()];
[[m_targetView window] addChildWindow:m_textIndicatorWindow.get() ordered:NSWindowAbove];
[m_textIndicatorWindow setReleasedWhenClosed:NO];
if (m_textIndicator->presentationTransition() != TextIndicatorPresentationTransition::None)
[m_textIndicatorLayer present];
if (lifetime == TextIndicatorLifetime::Temporary)
m_temporaryTextIndicatorTimer.startOneShot(WebCore::timeBeforeFadeStarts);
}
void TextIndicatorWindow::closeWindow()
{
if (!m_textIndicatorWindow)
return;
if ([m_textIndicatorLayer isFadingOut])
return;
m_temporaryTextIndicatorTimer.stop();
[[m_textIndicatorWindow parentWindow] removeChildWindow:m_textIndicatorWindow.get()];
[m_textIndicatorWindow close];
m_textIndicatorWindow = nullptr;
}
void TextIndicatorWindow::startFadeOut()
{
[m_textIndicatorLayer setFadingOut:YES];
RetainPtr<NSWindow> indicatorWindow = m_textIndicatorWindow;
[m_textIndicatorLayer hideWithCompletionHandler:[indicatorWindow] {
[[indicatorWindow parentWindow] removeChildWindow:indicatorWindow.get()];
[indicatorWindow close];
}];
}
} // namespace WebCore
#endif // PLATFORM(MAC)