File: infobar_container_controller.mm

package info (click to toggle)
chromium-browser 41.0.2272.118-1
  • links: PTS, VCS
  • area: main
  • in suites: jessie-kfreebsd
  • size: 2,189,132 kB
  • sloc: cpp: 9,691,462; ansic: 3,341,451; python: 712,689; asm: 518,779; xml: 208,926; java: 169,820; sh: 119,353; perl: 68,907; makefile: 28,311; yacc: 13,305; objc: 11,385; tcl: 3,186; cs: 2,225; sql: 2,217; lex: 2,215; lisp: 1,349; pascal: 1,256; awk: 407; ruby: 155; sed: 53; php: 14; exp: 11
file content (168 lines) | stat: -rw-r--r-- 5,949 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
// Copyright (c) 2011 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.

#import "chrome/browser/ui/cocoa/infobars/infobar_container_controller.h"

#include "base/logging.h"
#include "chrome/browser/infobars/infobar_service.h"
#import "chrome/browser/ui/cocoa/browser_window_controller.h"
#import "chrome/browser/ui/cocoa/infobars/infobar_cocoa.h"
#import "chrome/browser/ui/cocoa/infobars/infobar_container_cocoa.h"
#import "chrome/browser/ui/cocoa/infobars/infobar_controller.h"
#import "chrome/browser/ui/cocoa/location_bar/location_bar_view_mac.h"
#import "chrome/browser/ui/cocoa/view_id_util.h"
#include "components/infobars/core/confirm_infobar_delegate.h"
#include "components/infobars/core/infobar.h"
#include "components/infobars/core/infobar_container.h"

@interface InfoBarContainerController ()
// Removes |controller| from the list of controllers in this container and
// removes its view from the view hierarchy.  This method is safe to call while
// |controller| is still on the call stack.
- (void)removeController:(InfoBarController*)controller;
@end


@implementation InfoBarContainerController

@synthesize shouldSuppressTopInfoBarTip = shouldSuppressTopInfoBarTip_;

- (id)initWithResizeDelegate:(id<ViewResizer>)resizeDelegate {
  DCHECK(resizeDelegate);
  if ((self = [super initWithNibName:nil bundle:nil])) {
    // This view and its subviews use autoresizing masks, The starting frame
    // needs to be reasonably large, although its exactly values don't matter.
    // It cannot be NSZeroRect.
    base::scoped_nsobject<NSView> view(
        [[NSView alloc] initWithFrame:NSMakeRect(0, 0, 800, 100)]);
    [view setAutoresizingMask:NSViewWidthSizable | NSViewMinYMargin];
    view_id_util::SetID(view, VIEW_ID_INFO_BAR_CONTAINER);
    [self setView:view];

    resizeDelegate_ = resizeDelegate;
    containerCocoa_.reset(new InfoBarContainerCocoa(self));
    infobarControllers_.reset([[NSMutableArray alloc] init]);
  }
  return self;
}

- (void)dealloc {
  // Delete the container so that any remaining infobars are removed.
  containerCocoa_.reset();
  DCHECK_EQ([infobarControllers_ count], 0U);
  view_id_util::UnsetID([self view]);
  [super dealloc];
}

- (BrowserWindowController*)browserWindowController {
  id controller = [[[self view] window] windowController];
  if (![controller isKindOfClass:[BrowserWindowController class]])
    return nil;
  return controller;
}

- (CGFloat)infobarArrowX {
  LocationBarViewMac* locationBar =
      [[self browserWindowController] locationBarBridge];
  return locationBar->GetPageInfoBubblePoint().x;
}

- (void)changeWebContents:(content::WebContents*)contents {
  currentWebContents_ = contents;
  InfoBarService* infobar_service =
      contents ? InfoBarService::FromWebContents(contents) : NULL;
  containerCocoa_->ChangeInfoBarManager(infobar_service);
}

- (void)tabDetachedWithContents:(content::WebContents*)contents {
  if (currentWebContents_ == contents)
    [self changeWebContents:NULL];
}

- (CGFloat)overlappingTipHeight {
  return containerCocoa_->GetVerticalOverlap(NULL);
}

- (void)addInfoBar:(InfoBarCocoa*)infobar
          position:(NSUInteger)position {
  InfoBarController* controller = infobar->controller();
  [controller setContainerController:self];
  [infobarControllers_ insertObject:controller atIndex:position];

  NSView* relativeView = nil;
  if (position > 0)
    relativeView = [[infobarControllers_ objectAtIndex:position - 1] view];
  [[self view] addSubview:[controller view]
               positioned:NSWindowAbove
               relativeTo:relativeView];
}

- (void)removeInfoBar:(InfoBarCocoa*)infobar {
  [infobar->controller() infobarWillHide];
  [self removeController:infobar->controller()];
}

- (void)positionInfoBarsAndRedraw:(BOOL)isAnimating {
  if (isAnimating_ != isAnimating) {
    isAnimating_ = isAnimating;
    if ([resizeDelegate_ respondsToSelector:@selector(setAnimationInProgress:)])
      [resizeDelegate_ setAnimationInProgress:isAnimating_];
  }

  NSRect containerBounds = [[self view] bounds];
  int minY = 0;

  // Stack the infobars at the bottom of the view, starting with the
  // last infobar and working our way to the front of the array.  This
  // way we ensure that the first infobar added shows up on top, with
  // the others below.
  for (InfoBarController* controller in
           [infobarControllers_ reverseObjectEnumerator]) {
    NSRect frame;
    frame.origin.x = NSMinX(containerBounds);
    frame.origin.y = minY;
    frame.size.width = NSWidth(containerBounds);
    frame.size.height = [controller infobar]->total_height();
    [[controller view] setFrame:frame];

    minY += NSHeight(frame) - [controller infobar]->arrow_height();
    [controller layoutArrow];
  }

  [resizeDelegate_ resizeView:[self view] newHeight:[self heightOfInfoBars]];
}

- (void)setShouldSuppressTopInfoBarTip:(BOOL)flag {
  if (shouldSuppressTopInfoBarTip_ == flag)
    return;
  shouldSuppressTopInfoBarTip_ = flag;
  [self positionInfoBarsAndRedraw:isAnimating_];
}

- (void)removeController:(InfoBarController*)controller {
  if (![infobarControllers_ containsObject:controller])
    return;

  // This code can be executed while InfoBarController is still on the stack, so
  // we retain and autorelease the controller to prevent it from being
  // dealloc'ed too early.
  [[controller retain] autorelease];
  [[controller view] removeFromSuperview];
  [infobarControllers_ removeObject:controller];
}

- (void)setMaxTopArrowHeight:(NSInteger)height {
  containerCocoa_->SetMaxTopArrowHeight(height, containerCocoa_.get());
}

- (CGFloat)heightOfInfoBars {
  CGFloat totalHeight = 0;
  for (InfoBarController* controller in infobarControllers_.get()) {
    totalHeight += [controller infobar]->total_height() -
                   [controller infobar]->arrow_height();
  }
  return totalHeight;
}

@end