<commit_before>/*
 * _CPPopoverWindow.j
 * AppKit
 *
 * Created by <NAME>
 * Copyright 2011 <<EMAIL>>
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 */

@import <Foundation/CPObject.j>

@import "CPButton.j"
@import "CPMenu.j"
@import "CPPanel.j"

// Use forward declaration because this file is imported by CPPopover
@class CPPopover

@global CPApp
@global CPPopoverBehaviorSemitransient
@global CPPopoverBehaviorTransient
@global CPPopoverBehaviorApplicationDefined

CPClosableOnBlurWindowMask  = 1 << 4;
CPPopoverAppearanceMinimal  = 0;
CPPopoverAppearanceHUD      = 1;

// we don't start from 1 because CPWindow and so CPPanel already
// has this delegate bitmask identifier for 1, 2 and 3.
var _CPPopoverWindow_shouldClose_    = 1 << 4,
    _CPPopoverWindow_didClose_       = 1 << 5,
    _CPPopoverWindow_didShow_        = 1 << 6;


/*!
    @ignore

    This is a simple popover window like the one that pops up
    when you double click on a meeting in iCal.
*/
@implementation _CPPopoverWindow : CPPanel
{
    BOOL            _animates           @accessors(property=animates);
    id              _targetView         @accessors(property=targetView);
    int             _appearance         @accessors(getter=appearance);
    BOOL            _isClosing          @accessors(property=isClosing);
    BOOL            _isOpening          @accessors(property=isOpening);

    BOOL            _closeOnBlur;
    BOOL            _browserAnimates;
    BOOL            _isObservingFrame;
    BOOL            _shouldPerformAnimation;
    CPInteger       _implementedDelegateMethods;
    CGRect          _targetRect;
    CPWindow        _targetWindow;
    JSObject        _orderOutTransitionFunction;
    JSObject        _transitionCompleteFunction;
    JSObject        _orderFrontTransitionFunction;


}


#pragma mark -
#pragma mark Class methods

/*!
    Overrides the default windowView class loader.

    @param aStyleMask the window mask
    @return the windowView class
*/
+ (Class)_windowViewClassForStyleMask:(unsigned)aStyleMask
{
    return _CPPopoverWindowView;
}


#pragma mark -
#pragma mark Initialization

/*!
    Create and init a _CPPopoverWindow with given the given frame.

    @param aFrame the frame of the popover window
    @return ready to use _CPPopoverWindow
*/
- (id)initWithContentRect:(CGRect)aFrame
{
    return [self initWithContentRect:aFrame styleMask:0];
}

/*!
    Designated initializer. Create and init a _CPPopoverWindow with the given frame and style mask.

    @param aFrame the frame of the popover window
    @param styleMask the window style mask  (combine CPClosableWindowMask and CPClosableOnBlurWindowMask)
    @return ready to use _CPPopoverWindow
*/
- (id)initWithContentRect:(CGRect)aFrame styleMask:(unsigned)aStyleMask
{
    if (self = [super initWithContentRect:aFrame styleMask:aStyleMask])
    {
        _animates                   = YES;
        _isClosing                  = NO;
        _browserAnimates            = [self browserSupportsAnimation];
        _shouldPerformAnimation     = YES;
        _orderOutTransitionFunction = function() { [self _orderOutRecursively:YES]; };
        _isOpening                  = YES;

        [self setStyleMask:aStyleMask];
        [self setBecomesKeyOnlyIfNeeded:YES];
        [self setMovableByWindowBackground:YES];
        [self setHasShadow:NO];

        [self setCSS3Property:@"TransitionProperty" value:CPBrowserCSSProperty('transform') + @", opacity"];

        [_windowView setNeedsDisplay:YES];
    }

    return self;
}

#pragma mark -
#pragma mark Getters / Setters

- (void)setAppearance:(int)anAppearance
{
    if (_appearance === anAppearance)
        return;

    [_windowView setAppearance:anAppearance];
}

- (void)setStyleMask:(unsigned)aStyleMask
{
    _closeOnBlur = (aStyleMask & CPClosableOnBlurWindowMask);
}

- (void)setDelegate:(id)aDelegate
{
    if (_delegate === aDelegate)
        return;

    _delegate = aDelegate;
    _implementedDelegateMethods = 0;

    if ([_delegate respondsToSelector:@selector(_popoverWindowShouldClose:)])
        _implementedDelegateMethods |= _CPPopoverWindow_shouldClose_;

    if ([_delegate respondsToSelector:@selector(_popoverWindowDidClose:)])
        _implementedDelegateMethods |= _CPPopoverWindow_didClose_;

    if ([_delegate respondsToSelector:@selector(_popoverWindowDidShow:)])
        _implementedDelegateMethods |= _CPPopoverWindow_didShow_;
}

#pragma mark -
#pragma mark Observer

/*!
    @ignore
    Adds self as frame observer if not already observing it
*/
- (void)_addFrameObserver
{
    if (_isObservingFrame)
        return;

    _isObservingFrame = YES;
    [_targetView addObserver:self forKeyPath:@"frame" options:0 context:nil];
}

/*!
    @ignore
    Removes self as frame observer if already observing it
*/
- (void)_removeFrameObserver
{
    if (!_isObservingFrame)
        return;

    _isObservingFrame = NO;
    [_targetView removeObserver:self forKeyPath:@"frame"];
}

/*!
    Update the _CPPopoverWindow frame if a resize event is observed.
*/
- (void)observeValueForKeyPath:(CPString)aPath ofObject:(id)anObject change:(CPDictionary)theChange context:(void)aContext
{
    if (aPath === @"frame")
    {
        if (![_targetView window])
            return;

        var point = [self computeOriginFromRect:_targetRect ofView:_targetView preferredEdge:[_windowView preferredEdge]];<commit_msg>Fixed: CPPopover position does not update each time<commit_after>/*
 * _CPPopoverWindow.j
 * AppKit
 *
 * Created by <NAME>
 * Copyright 2011 <<EMAIL>>
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 */

@import <Foundation/CPObject.j>

@import "CPButton.j"
@import "CPMenu.j"
@import "CPPanel.j"

// Use forward declaration because this file is imported by CPPopover
@class CPPopover

@global CPApp
@global CPPopoverBehaviorSemitransient
@global CPPopoverBehaviorTransient
@global CPPopoverBehaviorApplicationDefined

CPClosableOnBlurWindowMask  = 1 << 4;
CPPopoverAppearanceMinimal  = 0;
CPPopoverAppearanceHUD      = 1;

// we don't start from 1 because CPWindow and so CPPanel already
// has this delegate bitmask identifier for 1, 2 and 3.
var _CPPopoverWindow_shouldClose_    = 1 << 4,
    _CPPopoverWindow_didClose_       = 1 << 5,
    _CPPopoverWindow_didShow_        = 1 << 6;


/*!
    @ignore

    This is a simple popover window like the one that pops up
    when you double click on a meeting in iCal.
*/
@implementation _CPPopoverWindow : CPPanel
{
    BOOL            _animates           @accessors(property=animates);
    id              _targetView         @accessors(property=targetView);
    int             _appearance         @accessors(getter=appearance);
    BOOL            _isClosing          @accessors(property=isClosing);
    BOOL            _isOpening          @accessors(property=isOpening);

    BOOL            _closeOnBlur;
    BOOL            _browserAnimates;
    BOOL            _isObservingFrame;
    BOOL            _shouldPerformAnimation;
    CPInteger       _implementedDelegateMethods;
    CGRect          _targetRect;
    CPWindow        _targetWindow;
    JSObject        _orderOutTransitionFunction;
    JSObject        _transitionCompleteFunction;
    JSObject        _orderFrontTransitionFunction;


}


#pragma mark -
#pragma mark Class methods

/*!
    Overrides the default windowView class loader.

    @param aStyleMask the window mask
    @return the windowView class
*/
+ (Class)_windowViewClassForStyleMask:(unsigned)aStyleMask
{
    return _CPPopoverWindowView;
}


#pragma mark -
#pragma mark Initialization

/*!
    Create and init a _CPPopoverWindow with given the given frame.

    @param aFrame the frame of the popover window
    @return ready to use _CPPopoverWindow
*/
- (id)initWithContentRect:(CGRect)aFrame
{
    return [self initWithContentRect:aFrame styleMask:0];
}

/*!
    Designated initializer. Create and init a _CPPopoverWindow with the given frame and style mask.

    @param aFrame the frame of the popover window
    @param styleMask the window style mask  (combine CPClosableWindowMask and CPClosableOnBlurWindowMask)
    @return ready to use _CPPopoverWindow
*/
- (id)initWithContentRect:(CGRect)aFrame styleMask:(unsigned)aStyleMask
{
    if (self = [super initWithContentRect:aFrame styleMask:aStyleMask])
    {
        _animates                   = YES;
        _isClosing                  = NO;
        _browserAnimates            = [self browserSupportsAnimation];
        _shouldPerformAnimation     = YES;
        _orderOutTransitionFunction = function() { [self _orderOutRecursively:YES]; };
        _isOpening                  = YES;

        [self setStyleMask:aStyleMask];
        [self setBecomesKeyOnlyIfNeeded:YES];
        [self setMovableByWindowBackground:YES];
        [self setHasShadow:NO];

        [self setCSS3Property:@"TransitionProperty" value:CPBrowserCSSProperty('transform') + @", opacity"];

        [_windowView setNeedsDisplay:YES];
    }

    return self;
}

#pragma mark -
#pragma mark Getters / Setters

- (void)setAppearance:(int)anAppearance
{
    if (_appearance === anAppearance)
        return;

    [_windowView setAppearance:anAppearance];
}

- (void)setStyleMask:(unsigned)aStyleMask
{
    _closeOnBlur = (aStyleMask & CPClosableOnBlurWindowMask);
}

- (void)setDelegate:(id)aDelegate
{
    if (_delegate === aDelegate)
        return;

    _delegate = aDelegate;
    _implementedDelegateMethods = 0;

    if ([_delegate respondsToSelector:@selector(_popoverWindowShouldClose:)])
        _implementedDelegateMethods |= _CPPopoverWindow_shouldClose_;

    if ([_delegate respondsToSelector:@selector(_popoverWindowDidClose:)])
        _implementedDelegateMethods |= _CPPopoverWindow_didClose_;

    if ([_delegate respondsToSelector:@selector(_popoverWindowDidShow:)])
        _implementedDelegateMethods |= _CPPopoverWindow_didShow_;
}

#pragma mark -
#pragma mark Observer

/*!
    @ignore
    Adds self as frame observer if not already observing it
*/
- (void)_addFrameObserver
{
    if (_isObservingFrame)
        return;

    _isObservingFrame = YES;

    var view = _targetView;

    while (view)
    {
        [view addObserver:self forKeyPath:@"frame" options:0 context:nil];
        view = [view superview];
    }
}

/*!
    @ignore
    Removes self as frame observer if already observing it
*/
- (void)_removeFrameObserver
{
    if (!_isObservingFrame)
        return;

    _isObservingFrame = NO;

    var view = _targetView;

    while (view)
    {
        [view removeObserver:self forKeyPath:@"frame"];
        view = [view superview];
    }
}

/*!
    Update the _CPPopoverWindow frame if a resize event is observed.
*/
- (void)observeValueForKeyPath:(CPString)aPath ofObject:(id)anObject change:(CPDictionary)theChange context:(void)aContext
{
    if (aPath === @"frame")
    {
        if (![_targetView window])
            return;

        var point = [self computeOriginFromRect:_targetRect ofView:_targetView preferredEdge:[_windowView preferredEdge]];
{'fraction_non_alphanumeric': 0.07870894677236694, 'fraction_numerical': 0.0056625141562853904, 'mean_word_length': 3.2339041095890413, 'pattern_counts': {'":': 0, '<': 27, '<?xml version=': 0, '>': 11, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6056812', 'n_tokens_mistral': 3674, 'n_tokens_neox': 3481, 'n_words': 1018}