infobar_controller.mm revision 0529e5d033099cbfc42635f6f6183833b09dff6e
1// Copyright (c) 2012 The Chromium Authors. All rights reserved. 2// Use of this source code is governed by a BSD-style license that can be 3// found in the LICENSE file. 4 5#import "chrome/browser/ui/cocoa/infobars/infobar_controller.h" 6 7#include "base/logging.h" 8#include "base/mac/bundle_locations.h" 9#include "base/mac/mac_util.h" 10#include "chrome/browser/infobars/infobar_service.h" 11#import "chrome/browser/ui/cocoa/animatable_view.h" 12#import "chrome/browser/ui/cocoa/browser_window_controller.h" 13#import "chrome/browser/ui/cocoa/hyperlink_text_view.h" 14#import "chrome/browser/ui/cocoa/image_button_cell.h" 15#include "chrome/browser/ui/cocoa/infobars/infobar_cocoa.h" 16#import "chrome/browser/ui/cocoa/infobars/infobar_container_cocoa.h" 17#import "chrome/browser/ui/cocoa/infobars/infobar_container_controller.h" 18#import "chrome/browser/ui/cocoa/infobars/infobar_gradient_view.h" 19#import "chrome/browser/ui/cocoa/location_bar/location_bar_view_mac.h" 20#include "grit/theme_resources.h" 21#include "grit/ui_resources.h" 22#include "ui/gfx/image/image.h" 23 24@interface InfoBarController () 25// Sets |label_| based on |labelPlaceholder_|, sets |labelPlaceholder_| to nil. 26- (void)initializeLabel; 27@end 28 29@implementation InfoBarController 30 31@synthesize containerController = containerController_; 32 33- (id)initWithInfoBar:(InfoBarCocoa*)infobar { 34 if ((self = [super initWithNibName:@"InfoBar" 35 bundle:base::mac::FrameworkBundle()])) { 36 DCHECK(infobar); 37 infobar_ = infobar->GetWeakPtr(); 38 } 39 return self; 40} 41 42// All infobars have an icon, so we set up the icon in the base class 43// awakeFromNib. 44- (void)awakeFromNib { 45 [[closeButton_ cell] setImageID:IDR_CLOSE_1 46 forButtonState:image_button_cell::kDefaultState]; 47 [[closeButton_ cell] setImageID:IDR_CLOSE_1_H 48 forButtonState:image_button_cell::kHoverState]; 49 [[closeButton_ cell] setImageID:IDR_CLOSE_1_P 50 forButtonState:image_button_cell::kPressedState]; 51 [[closeButton_ cell] setImageID:IDR_CLOSE_1 52 forButtonState:image_button_cell::kDisabledState]; 53 54 if (![self delegate]->GetIcon().IsEmpty()) { 55 [image_ setImage:[self delegate]->GetIcon().ToNSImage()]; 56 } else { 57 // No icon, remove it from the view and grow the textfield to include the 58 // space. 59 NSRect imageFrame = [image_ frame]; 60 NSRect labelFrame = [labelPlaceholder_ frame]; 61 labelFrame.size.width += NSMinX(imageFrame) - NSMinX(labelFrame); 62 labelFrame.origin.x = imageFrame.origin.x; 63 [image_ removeFromSuperview]; 64 image_ = nil; 65 [labelPlaceholder_ setFrame:labelFrame]; 66 } 67 [self initializeLabel]; 68 69 [self addAdditionalControls]; 70 71 [infoBarView_ setInfobarType:[self delegate]->GetInfoBarType()]; 72} 73 74- (void)dealloc { 75 [okButton_ setTarget:nil]; 76 [cancelButton_ setTarget:nil]; 77 [closeButton_ setTarget:nil]; 78 [super dealloc]; 79} 80 81- (InfoBarCocoa*)infobar { 82 return infobar_.get(); 83} 84 85// Called when someone clicks on the embedded link. 86- (BOOL)textView:(NSTextView*)textView 87 clickedOnLink:(id)link 88 atIndex:(NSUInteger)charIndex { 89 if ([self respondsToSelector:@selector(linkClicked)]) 90 [self performSelector:@selector(linkClicked)]; 91 return YES; 92} 93 94- (BOOL)isOwned { 95 return infobar_ && infobar_->OwnerCocoa() != NULL; 96} 97 98// Called when someone clicks on the ok button. 99- (void)ok:(id)sender { 100 // Subclasses must override this method if they do not hide the ok button. 101 NOTREACHED(); 102} 103 104// Called when someone clicks on the cancel button. 105- (void)cancel:(id)sender { 106 // Subclasses must override this method if they do not hide the cancel button. 107 NOTREACHED(); 108} 109 110// Called when someone clicks on the close button. 111- (void)dismiss:(id)sender { 112 if (![self isOwned]) 113 return; 114 [self delegate]->InfoBarDismissed(); 115 [self removeSelf]; 116} 117 118- (void)removeSelf { 119 infobar_->RemoveSelf(); 120} 121 122- (void)addAdditionalControls { 123 // Default implementation does nothing. 124} 125 126- (void)infobarWillHide { 127} 128 129- (void)infobarWillClose { 130} 131 132- (void)removeButtons { 133 // Extend the label all the way across. 134 NSRect labelFrame = [label_.get() frame]; 135 labelFrame.size.width = NSMaxX([cancelButton_ frame]) - NSMinX(labelFrame); 136 [okButton_ removeFromSuperview]; 137 okButton_ = nil; 138 [cancelButton_ removeFromSuperview]; 139 cancelButton_ = nil; 140 [label_.get() setFrame:labelFrame]; 141} 142 143- (void)layoutArrow { 144 [infoBarView_ setArrowHeight:infobar_->arrow_height()]; 145 [infoBarView_ setArrowHalfWidth:infobar_->arrow_half_width()]; 146 [infoBarView_ setHasTip:![containerController_ shouldSuppressTopInfoBarTip]]; 147 148 // Convert from window to view coordinates. 149 NSPoint point = NSMakePoint([containerController_ infobarArrowX], 0); 150 point = [infoBarView_ convertPoint:point fromView:nil]; 151 [infoBarView_ setArrowX:point.x]; 152} 153 154- (void)disablePopUpMenu:(NSMenu*)menu { 155 // If the menu is re-opened, prevent queries to update items. 156 [menu setDelegate:nil]; 157 158 // Prevent target/action messages to the controller. 159 for (NSMenuItem* item in [menu itemArray]) { 160 [item setEnabled:NO]; 161 [item setTarget:nil]; 162 } 163} 164 165- (infobars::InfoBarDelegate*)delegate { 166 return infobar_->delegate(); 167} 168 169- (void)initializeLabel { 170 // Replace the label placeholder NSTextField with the real label NSTextView. 171 // The former doesn't show links in a nice way, but the latter can't be added 172 // in IB without a containing scroll view, so create the NSTextView 173 // programmatically. 174 base::scoped_nsobject<HyperlinkTextView> newLabel( 175 [[HyperlinkTextView alloc] initWithFrame:[labelPlaceholder_ frame]]); 176 [newLabel setDrawsBackgroundUsingSuperview:YES]; 177 [newLabel setAutoresizingMask:[labelPlaceholder_ autoresizingMask]]; 178 [[labelPlaceholder_ superview] 179 replaceSubview:labelPlaceholder_ with:newLabel]; 180 labelPlaceholder_ = nil; // Now released. 181 [newLabel setDelegate:self]; 182 183 label_.reset(newLabel.release()); 184} 185 186@end 187