| Index: chrome/browser/ui/cocoa/panels/panel_stack_window_cocoa.mm
|
| diff --git a/chrome/browser/ui/cocoa/panels/panel_stack_window_cocoa.mm b/chrome/browser/ui/cocoa/panels/panel_stack_window_cocoa.mm
|
| deleted file mode 100644
|
| index 01b5edffdcbc3dfb507ff51f8f5c5281b43e710f..0000000000000000000000000000000000000000
|
| --- a/chrome/browser/ui/cocoa/panels/panel_stack_window_cocoa.mm
|
| +++ /dev/null
|
| @@ -1,385 +0,0 @@
|
| -// Copyright (c) 2013 The Chromium Authors. All rights reserved.
|
| -// Use of this source code is governed by a BSD-style license that can be
|
| -// found in the LICENSE file.
|
| -
|
| -#include "chrome/browser/ui/cocoa/panels/panel_stack_window_cocoa.h"
|
| -
|
| -#include "base/logging.h"
|
| -#include "base/strings/sys_string_conversions.h"
|
| -#import "chrome/browser/ui/cocoa/panels/panel_cocoa.h"
|
| -#import "chrome/browser/ui/cocoa/panels/panel_utils_cocoa.h"
|
| -#include "chrome/browser/ui/panels/panel.h"
|
| -#include "chrome/browser/ui/panels/panel_manager.h"
|
| -#include "chrome/browser/ui/panels/stacked_panel_collection.h"
|
| -#include "ui/base/cocoa/window_size_constants.h"
|
| -#include "ui/gfx/canvas.h"
|
| -#include "ui/gfx/geometry/vector2d.h"
|
| -#include "ui/gfx/image/image.h"
|
| -#include "ui/gfx/image/image_skia.h"
|
| -#include "ui/gfx/image/image_skia_rep.h"
|
| -#include "ui/snapshot/snapshot.h"
|
| -
|
| -// The delegate class to receive the notification from NSViewAnimation.
|
| -@interface BatchBoundsAnimationDelegate : NSObject<NSAnimationDelegate> {
|
| - @private
|
| - PanelStackWindowCocoa* window_; // Weak pointer.
|
| -}
|
| -
|
| -// Called when NSViewAnimation finishes the animation.
|
| -- (void)animationDidEnd:(NSAnimation*)animation;
|
| -@end
|
| -
|
| -@implementation BatchBoundsAnimationDelegate
|
| -
|
| -- (id)initWithWindow:(PanelStackWindowCocoa*)window {
|
| - if ((self = [super init]))
|
| - window_ = window;
|
| - return self;
|
| -}
|
| -
|
| -- (void)animationDidEnd:(NSAnimation*)animation {
|
| - window_->BoundsUpdateAnimationEnded();
|
| -}
|
| -
|
| -@end
|
| -
|
| -// static
|
| -NativePanelStackWindow* NativePanelStackWindow::Create(
|
| - NativePanelStackWindowDelegate* delegate) {
|
| - return new PanelStackWindowCocoa(delegate);
|
| -}
|
| -
|
| -PanelStackWindowCocoa::PanelStackWindowCocoa(
|
| - NativePanelStackWindowDelegate* delegate)
|
| - : delegate_(delegate),
|
| - attention_request_id_(0),
|
| - bounds_updates_started_(false),
|
| - animate_bounds_updates_(false),
|
| - bounds_animation_(nil) {
|
| - DCHECK(delegate);
|
| - bounds_animation_delegate_.reset(
|
| - [[BatchBoundsAnimationDelegate alloc] initWithWindow:this]);
|
| -}
|
| -
|
| -PanelStackWindowCocoa::~PanelStackWindowCocoa() {
|
| -}
|
| -
|
| -void PanelStackWindowCocoa::Close() {
|
| - TerminateBoundsAnimation();
|
| - [window_ close];
|
| -}
|
| -
|
| -void PanelStackWindowCocoa::AddPanel(Panel* panel) {
|
| - panels_.push_back(panel);
|
| -
|
| - EnsureWindowCreated();
|
| -
|
| - // Make the stack window own the panel window such that all panels window
|
| - // could be moved simulatenously when the stack window is moved.
|
| - [window_ addChildWindow:panel->GetNativeWindow() ordered:NSWindowAbove];
|
| -
|
| - UpdateStackWindowBounds();
|
| -}
|
| -
|
| -void PanelStackWindowCocoa::RemovePanel(Panel* panel) {
|
| - if (IsAnimatingPanelBounds()) {
|
| - // This panel is gone. We should not perform any update to it.
|
| - bounds_updates_.erase(panel);
|
| - }
|
| -
|
| - panels_.remove(panel);
|
| -
|
| - // If the native panel is closed, the native window should already be gone.
|
| - if (!static_cast<PanelCocoa*>(panel->native_panel())->IsClosed())
|
| - [window_ removeChildWindow:panel->GetNativeWindow()];
|
| -
|
| - UpdateStackWindowBounds();
|
| -}
|
| -
|
| -void PanelStackWindowCocoa::MergeWith(NativePanelStackWindow* another) {
|
| - PanelStackWindowCocoa* another_stack =
|
| - static_cast<PanelStackWindowCocoa*>(another);
|
| -
|
| - for (Panels::const_iterator iter = another_stack->panels_.begin();
|
| - iter != another_stack->panels_.end(); ++iter) {
|
| - Panel* panel = *iter;
|
| - panels_.push_back(panel);
|
| -
|
| - // Change the panel window owner.
|
| - NSWindow* panel_window = panel->GetNativeWindow();
|
| - [another_stack->window_ removeChildWindow:panel_window];
|
| - [window_ addChildWindow:panel_window ordered:NSWindowAbove];
|
| - }
|
| - another_stack->panels_.clear();
|
| -
|
| - UpdateStackWindowBounds();
|
| -}
|
| -
|
| -bool PanelStackWindowCocoa::IsEmpty() const {
|
| - return panels_.empty();
|
| -}
|
| -
|
| -bool PanelStackWindowCocoa::HasPanel(Panel* panel) const {
|
| - return std::find(panels_.begin(), panels_.end(), panel) != panels_.end();
|
| -}
|
| -
|
| -void PanelStackWindowCocoa::MovePanelsBy(const gfx::Vector2d& delta) {
|
| - // Moving the background stack window will cause all foreground panels window
|
| - // being moved simulatenously.
|
| - gfx::Rect enclosing_bounds = GetStackWindowBounds();
|
| - enclosing_bounds.Offset(delta);
|
| - NSRect frame = cocoa_utils::ConvertRectToCocoaCoordinates(enclosing_bounds);
|
| - [window_ setFrame:frame display:NO];
|
| -
|
| - // We also need to update the panel bounds.
|
| - for (Panels::const_iterator iter = panels_.begin();
|
| - iter != panels_.end(); ++iter) {
|
| - Panel* panel = *iter;
|
| - gfx::Rect bounds = panel->GetBounds();
|
| - bounds.Offset(delta);
|
| - panel->SetPanelBoundsInstantly(bounds);
|
| - }
|
| -}
|
| -
|
| -void PanelStackWindowCocoa::BeginBatchUpdatePanelBounds(bool animate) {
|
| - // If the batch animation is still in progress, continue the animation
|
| - // with the new target bounds even we want to update the bounds instantly
|
| - // this time.
|
| - if (!bounds_updates_started_) {
|
| - animate_bounds_updates_ = animate;
|
| - bounds_updates_started_ = true;
|
| - }
|
| -}
|
| -
|
| -void PanelStackWindowCocoa::AddPanelBoundsForBatchUpdate(
|
| - Panel* panel, const gfx::Rect& new_bounds) {
|
| - DCHECK(bounds_updates_started_);
|
| -
|
| - // No need to track it if no change is needed.
|
| - if (panel->GetBounds() == new_bounds)
|
| - return;
|
| -
|
| - // Old bounds are stored as the map value.
|
| - bounds_updates_[panel] = panel->GetBounds();
|
| -
|
| - // New bounds are directly applied to the value stored in native panel
|
| - // window.
|
| - static_cast<PanelCocoa*>(panel->native_panel())->set_cached_bounds_directly(
|
| - new_bounds);
|
| -}
|
| -
|
| -void PanelStackWindowCocoa::EndBatchUpdatePanelBounds() {
|
| - DCHECK(bounds_updates_started_);
|
| -
|
| - // No need to proceed with the animation when the bounds update list is
|
| - // empty or animation was not requested.
|
| - if (bounds_updates_.empty() || !animate_bounds_updates_) {
|
| - // Set the bounds directly when the update list is not empty.
|
| - if (!bounds_updates_.empty()) {
|
| - for (BoundsUpdates::const_iterator iter = bounds_updates_.begin();
|
| - iter != bounds_updates_.end(); ++iter) {
|
| - Panel* panel = iter->first;
|
| - NSRect frame =
|
| - cocoa_utils::ConvertRectToCocoaCoordinates(panel->GetBounds());
|
| - [panel->GetNativeWindow() setFrame:frame display:YES animate:NO];
|
| - }
|
| - bounds_updates_.clear();
|
| - UpdateStackWindowBounds();
|
| - }
|
| -
|
| - bounds_updates_started_ = false;
|
| - delegate_->PanelBoundsBatchUpdateCompleted();
|
| - return;
|
| - }
|
| -
|
| - // Terminate previous animation, if it is still playing.
|
| - TerminateBoundsAnimation();
|
| -
|
| - // Find out if we need the animation for each panel. If the batch updates
|
| - // consist of only moving all panels by delta offset, moving the background
|
| - // window would be enough.
|
| -
|
| - // If all the panels move and don't resize, just animate the underlying
|
| - // parent window. Otherwise, animate each individual panel.
|
| - bool need_to_animate_individual_panels = false;
|
| - if (bounds_updates_.size() == panels_.size()) {
|
| - gfx::Vector2d delta;
|
| - for (BoundsUpdates::const_iterator iter = bounds_updates_.begin();
|
| - iter != bounds_updates_.end(); ++iter) {
|
| - gfx::Rect old_bounds = iter->second;
|
| - gfx::Rect new_bounds = iter->first->GetBounds();
|
| -
|
| - // Size should not be changed.
|
| - if (old_bounds.width() != new_bounds.width() ||
|
| - old_bounds.height() != new_bounds.height()) {
|
| - need_to_animate_individual_panels = true;
|
| - break;
|
| - }
|
| -
|
| - // Origin offset should be same.
|
| - if (iter == bounds_updates_.begin()) {
|
| - delta = new_bounds.origin() - old_bounds.origin();
|
| - } else if (!(delta == new_bounds.origin() - old_bounds.origin())) {
|
| - need_to_animate_individual_panels = true;
|
| - break;
|
| - }
|
| - }
|
| - } else {
|
| - need_to_animate_individual_panels = true;
|
| - }
|
| -
|
| - int num_of_animations = 1;
|
| - if (need_to_animate_individual_panels)
|
| - num_of_animations += bounds_updates_.size();
|
| - base::scoped_nsobject<NSMutableArray> animations(
|
| - [[NSMutableArray alloc] initWithCapacity:num_of_animations]);
|
| -
|
| - // Add the animation for each panel in the update list.
|
| - if (need_to_animate_individual_panels) {
|
| - for (BoundsUpdates::const_iterator iter = bounds_updates_.begin();
|
| - iter != bounds_updates_.end(); ++iter) {
|
| - Panel* panel = iter->first;
|
| - NSRect panel_frame =
|
| - cocoa_utils::ConvertRectToCocoaCoordinates(panel->GetBounds());
|
| - NSDictionary* animation = [NSDictionary dictionaryWithObjectsAndKeys:
|
| - panel->GetNativeWindow(), NSViewAnimationTargetKey,
|
| - [NSValue valueWithRect:panel_frame], NSViewAnimationEndFrameKey,
|
| - nil];
|
| - [animations addObject:animation];
|
| - }
|
| - }
|
| -
|
| - // Compute the final bounds that enclose all panels after the animation.
|
| - gfx::Rect enclosing_bounds;
|
| - for (Panels::const_iterator iter = panels_.begin();
|
| - iter != panels_.end(); ++iter) {
|
| - gfx::Rect target_bounds = (*iter)->GetBounds();
|
| - enclosing_bounds = UnionRects(enclosing_bounds, target_bounds);
|
| - }
|
| -
|
| - // Add the animation for the background stack window.
|
| - NSRect enclosing_frame =
|
| - cocoa_utils::ConvertRectToCocoaCoordinates(enclosing_bounds);
|
| - NSDictionary* stack_animation = [NSDictionary dictionaryWithObjectsAndKeys:
|
| - window_.get(), NSViewAnimationTargetKey,
|
| - [NSValue valueWithRect:enclosing_frame], NSViewAnimationEndFrameKey,
|
| - nil];
|
| - [animations addObject:stack_animation];
|
| -
|
| - // Start all the animations.
|
| - // |bounds_animation_| is released when the animation ends.
|
| - bounds_animation_ =
|
| - [[NSViewAnimation alloc] initWithViewAnimations:animations];
|
| - [bounds_animation_ setDelegate:bounds_animation_delegate_.get()];
|
| - [bounds_animation_ setDuration:PanelManager::AdjustTimeInterval(0.18)];
|
| - [bounds_animation_ setFrameRate:0.0];
|
| - [bounds_animation_ setAnimationBlockingMode: NSAnimationNonblocking];
|
| - [bounds_animation_ startAnimation];
|
| -}
|
| -
|
| -bool PanelStackWindowCocoa::IsAnimatingPanelBounds() const {
|
| - return bounds_updates_started_ && animate_bounds_updates_;
|
| -}
|
| -
|
| -void PanelStackWindowCocoa::BoundsUpdateAnimationEnded() {
|
| - bounds_updates_started_ = false;
|
| -
|
| - for (BoundsUpdates::const_iterator iter = bounds_updates_.begin();
|
| - iter != bounds_updates_.end(); ++iter) {
|
| - Panel* panel = iter->first;
|
| - panel->manager()->OnPanelAnimationEnded(panel);
|
| - }
|
| - bounds_updates_.clear();
|
| -
|
| - delegate_->PanelBoundsBatchUpdateCompleted();
|
| -}
|
| -
|
| -void PanelStackWindowCocoa::Minimize() {
|
| - // Provide the custom miniwindow image since there is nothing painted for
|
| - // the background stack window.
|
| - gfx::Size stack_window_size = GetStackWindowBounds().size();
|
| - gfx::Canvas canvas(stack_window_size, 1.0f, true);
|
| - int y = 0;
|
| - Panels::const_iterator iter = panels_.begin();
|
| - for (; iter != panels_.end(); ++iter) {
|
| - Panel* panel = *iter;
|
| - gfx::Rect snapshot_bounds = gfx::Rect(panel->GetBounds().size());
|
| - std::vector<unsigned char> png;
|
| - if (!ui::GrabWindowSnapshot(panel->GetNativeWindow(),
|
| - &png,
|
| - snapshot_bounds))
|
| - break;
|
| - gfx::Image snapshot_image = gfx::Image::CreateFrom1xPNGBytes(
|
| - &(png[0]), png.size());
|
| - canvas.DrawImageInt(snapshot_image.AsImageSkia(), 0, y);
|
| - y += snapshot_bounds.height();
|
| - }
|
| - if (iter == panels_.end()) {
|
| - gfx::Image image(gfx::ImageSkia(canvas.ExtractImageRep()));
|
| - [window_ setMiniwindowImage:image.AsNSImage()];
|
| - }
|
| -
|
| - [window_ miniaturize:nil];
|
| -}
|
| -
|
| -bool PanelStackWindowCocoa::IsMinimized() const {
|
| - return [window_ isMiniaturized];
|
| -}
|
| -
|
| -void PanelStackWindowCocoa::DrawSystemAttention(bool draw_attention) {
|
| - BOOL is_drawing_attention = attention_request_id_ != 0;
|
| - if (draw_attention == is_drawing_attention)
|
| - return;
|
| -
|
| - if (draw_attention) {
|
| - attention_request_id_ = [NSApp requestUserAttention:NSCriticalRequest];
|
| - } else {
|
| - [NSApp cancelUserAttentionRequest:attention_request_id_];
|
| - attention_request_id_ = 0;
|
| - }
|
| -}
|
| -
|
| -void PanelStackWindowCocoa::OnPanelActivated(Panel* panel) {
|
| - // Nothing to do.
|
| -}
|
| -
|
| -void PanelStackWindowCocoa::TerminateBoundsAnimation() {
|
| - if (!bounds_animation_)
|
| - return;
|
| - [bounds_animation_ stopAnimation];
|
| - [bounds_animation_ setDelegate:nil];
|
| - [bounds_animation_ release];
|
| - bounds_animation_ = nil;
|
| -}
|
| -
|
| -gfx::Rect PanelStackWindowCocoa::GetStackWindowBounds() const {
|
| - gfx::Rect enclosing_bounds;
|
| - for (Panels::const_iterator iter = panels_.begin();
|
| - iter != panels_.end(); ++iter) {
|
| - Panel* panel = *iter;
|
| - enclosing_bounds = UnionRects(enclosing_bounds, panel->GetBounds());
|
| - }
|
| - return enclosing_bounds;
|
| -}
|
| -
|
| -void PanelStackWindowCocoa::UpdateStackWindowBounds() {
|
| - NSRect enclosing_bounds =
|
| - cocoa_utils::ConvertRectToCocoaCoordinates(GetStackWindowBounds());
|
| - [window_ setFrame:enclosing_bounds display:NO];
|
| -}
|
| -
|
| -void PanelStackWindowCocoa::EnsureWindowCreated() {
|
| - if (window_)
|
| - return;
|
| -
|
| - window_.reset(
|
| - [[NSWindow alloc] initWithContentRect:ui::kWindowSizeDeterminedLater
|
| - styleMask:NSBorderlessWindowMask
|
| - backing:NSBackingStoreBuffered
|
| - defer:NO]);
|
| - [window_ setBackgroundColor:[NSColor clearColor]];
|
| - [window_ setHasShadow:YES];
|
| - [window_ setLevel:NSNormalWindowLevel];
|
| - [window_ orderFront:nil];
|
| - [window_ setTitle:base::SysUTF16ToNSString(delegate_->GetTitle())];
|
| -}
|
|
|