Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(36)

Side by Side Diff: chrome/browser/cocoa/translate/translate_infobar_base.mm

Issue 2804035: Clean up mac translate bars. (Closed)
Patch Set: Fixes. Created 10 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2010 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #import <Cocoa/Cocoa.h> 5 #import <Cocoa/Cocoa.h>
6 #import "chrome/browser/cocoa/translate/translate_infobar_base.h" 6 #import "chrome/browser/cocoa/translate/translate_infobar_base.h"
7 7
8 #include "app/l10n_util.h" 8 #include "app/l10n_util.h"
9 #include "base/histogram.h" 9 #include "base/histogram.h"
10 #include "base/logging.h" // for NOTREACHED() 10 #include "base/logging.h" // for NOTREACHED()
(...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after
115 case kTranslationError: 115 case kTranslationError:
116 infobar_controller = 116 infobar_controller =
117 [[TranslateMessageInfobarController alloc] initWithDelegate:this]; 117 [[TranslateMessageInfobarController alloc] initWithDelegate:this];
118 break; 118 break;
119 default: 119 default:
120 NOTREACHED(); 120 NOTREACHED();
121 } 121 }
122 return new InfoBar(infobar_controller); 122 return new InfoBar(infobar_controller);
123 } 123 }
124 124
125 @implementation TranslateInfoBarControllerBase (FrameChangeObserver)
126
127 // Triggered when the frame changes. This will figure out what size and
128 // visibility the options popup should be.
129 - (void)didChangeFrame:(NSNotification*)notification {
130 [self adjustOptionsButtonSizeAndVisibilityForView:
131 [[self visibleControls] lastObject]];
132 }
133
134 @end
135
136
125 @interface TranslateInfoBarControllerBase (Private) 137 @interface TranslateInfoBarControllerBase (Private)
126 138
127 // Removes all controls so that layout can add in only the controls 139 // Removes all controls so that layout can add in only the controls
128 // required. 140 // required.
129 - (void)clearAllControls; 141 - (void)clearAllControls;
130 142
131 // Create all the various controls we need for the toolbar. 143 // Create all the various controls we need for the toolbar.
132 - (void)constructViews; 144 - (void)constructViews;
133 145
134 // Reloads text for all labels for the current state. 146 // Reloads text for all labels for the current state.
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after
217 229
218 - (void)loadLabelText { 230 - (void)loadLabelText {
219 // Do nothing by default, should be implemented by subclasses. 231 // Do nothing by default, should be implemented by subclasses.
220 } 232 }
221 233
222 - (void)updateState { 234 - (void)updateState {
223 [self loadLabelText]; 235 [self loadLabelText];
224 [self clearAllControls]; 236 [self clearAllControls];
225 [self showVisibleControls:[self visibleControls]]; 237 [self showVisibleControls:[self visibleControls]];
226 [self layout]; 238 [self layout];
239 [self adjustOptionsButtonSizeAndVisibilityForView:
240 [[self visibleControls] lastObject]];
227 } 241 }
228 242
229 - (void)setInfoBarGradientColor { 243 - (void)setInfoBarGradientColor {
230 NSColor* startingColor = [NSColor colorWithCalibratedWhite:0.93 alpha:1.0]; 244 NSColor* startingColor = [NSColor colorWithCalibratedWhite:0.93 alpha:1.0];
231 NSColor* endingColor = [NSColor colorWithCalibratedWhite:0.85 alpha:1.0]; 245 NSColor* endingColor = [NSColor colorWithCalibratedWhite:0.85 alpha:1.0];
232 NSGradient* translateInfoBarGradient = 246 NSGradient* translateInfoBarGradient =
233 [[[NSGradient alloc] initWithStartingColor:startingColor 247 [[[NSGradient alloc] initWithStartingColor:startingColor
234 endingColor:endingColor] autorelease]; 248 endingColor:endingColor] autorelease];
235 249
236 [infoBarView_ setGradient:translateInfoBarGradient]; 250 [infoBarView_ setGradient:translateInfoBarGradient];
237 [infoBarView_ 251 [infoBarView_
238 setStrokeColor:[NSColor colorWithCalibratedWhite:0.75 alpha:1.0]]; 252 setStrokeColor:[NSColor colorWithCalibratedWhite:0.75 alpha:1.0]];
239 } 253 }
240 254
241 - (void)removeOkCancelButtons { 255 - (void)removeOkCancelButtons {
242 // Removing okButton_ & cancelButton_ from the view may cause them 256 // Removing okButton_ & cancelButton_ from the view may cause them
243 // to be released and since we can still access them from other areas 257 // to be released and since we can still access them from other areas
244 // in the code later, we need them to be nil when this happens. 258 // in the code later, we need them to be nil when this happens.
245 [okButton_ removeFromSuperview]; 259 [okButton_ removeFromSuperview];
246 okButton_ = nil; 260 okButton_ = nil;
247 [cancelButton_ removeFromSuperview]; 261 [cancelButton_ removeFromSuperview];
248 cancelButton_ = nil; 262 cancelButton_ = nil;
249 } 263 }
250 264
251 - (void)clearAllControls { 265 - (void)clearAllControls {
252 // Step 1: remove all controls from the infobar so we have a clean slate. 266 // Step 1: remove all controls from the infobar so we have a clean slate.
253 NSArray *allControls = [NSArray arrayWithObjects:label2_.get(), label3_.get(), 267 NSArray *allControls = [self allControls];
254 fromLanguagePopUp_.get(), toLanguagePopUp_.get(),
255 showOriginalButton_.get(), tryAgainButton_.get(), nil];
256 268
257 for (NSControl* control in allControls) { 269 for (NSControl* control in allControls) {
258 if ([control superview]) 270 if ([control superview])
259 [control removeFromSuperview]; 271 [control removeFromSuperview];
260 } 272 }
261 } 273 }
262 274
263 - (void)showVisibleControls:(NSArray*)visibleControls { 275 - (void)showVisibleControls:(NSArray*)visibleControls {
264 NSRect optionsFrame = [optionsPopUp_ frame]; 276 NSRect optionsFrame = [optionsPopUp_ frame];
265 for (NSControl* control in visibleControls) { 277 for (NSControl* control in visibleControls) {
(...skipping 19 matching lines...) Expand all
285 } 297 }
286 298
287 - (void)layout { 299 - (void)layout {
288 300
289 } 301 }
290 302
291 - (NSArray*)visibleControls { 303 - (NSArray*)visibleControls {
292 return [NSArray array]; 304 return [NSArray array];
293 } 305 }
294 306
295 - (void) rebuildOptionsMenu { 307 - (void)rebuildOptionsMenu:(BOOL)hideTitle {
296 // The options model doesn't know how to handle state transitions, so rebuild 308 // The options model doesn't know how to handle state transitions, so rebuild
297 // it each time through here. 309 // it each time through here.
298 optionsMenuModel_.reset( 310 optionsMenuModel_.reset(
299 new OptionsMenuModel([self delegate])); 311 new OptionsMenuModel([self delegate]));
300 312
301 [optionsPopUp_ removeAllItems]; 313 [optionsPopUp_ removeAllItems];
302 // Set title. 314 // Set title.
303 NSString* optionsLabel = 315 NSString* optionsLabel = hideTitle ? @"" :
304 l10n_util::GetNSString(IDS_TRANSLATE_INFOBAR_OPTIONS); 316 l10n_util::GetNSString(IDS_TRANSLATE_INFOBAR_OPTIONS);
305 [optionsPopUp_ addItemWithTitle:optionsLabel]; 317 [optionsPopUp_ addItemWithTitle:optionsLabel];
306 318
307 // Populate options menu. 319 // Populate options menu.
308 NSMenu* optionsMenu = [optionsPopUp_ menu]; 320 NSMenu* optionsMenu = [optionsPopUp_ menu];
309 [optionsMenu setAutoenablesItems:NO]; 321 [optionsMenu setAutoenablesItems:NO];
310 for (int i = 0; i < optionsMenuModel_->GetItemCount(); ++i) { 322 for (int i = 0; i < optionsMenuModel_->GetItemCount(); ++i) {
311 NSString* title = base::SysUTF16ToNSString( 323 NSString* title = base::SysUTF16ToNSString(
312 optionsMenuModel_->GetLabelAt(i)); 324 optionsMenuModel_->GetLabelAt(i));
313 int cmd = optionsMenuModel_->GetCommandIdAt(i); 325 int cmd = optionsMenuModel_->GetCommandIdAt(i);
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after
388 // Set ourselves as the delegate for the options menu so we can populate it 400 // Set ourselves as the delegate for the options menu so we can populate it
389 // dynamically. 401 // dynamically.
390 [[optionsPopUp_ menu] setDelegate:self]; 402 [[optionsPopUp_ menu] setDelegate:self];
391 403
392 // Replace label_ with label1_ so we get a consistent look between all the 404 // Replace label_ with label1_ so we get a consistent look between all the
393 // labels we display in the translate view. 405 // labels we display in the translate view.
394 [[label_ superview] replaceSubview:label_ with:label1_.get()]; 406 [[label_ superview] replaceSubview:label_ with:label1_.get()];
395 label_.reset(); // Now released. 407 label_.reset(); // Now released.
396 408
397 // Populate contextual menus. 409 // Populate contextual menus.
398 [self rebuildOptionsMenu]; 410 [self rebuildOptionsMenu:NO];
399 [self populateLanguageMenus]; 411 [self populateLanguageMenus];
400 412
401 // Set OK & Cancel text. 413 // Set OK & Cancel text.
402 [okButton_ setTitle:GetNSStringWithFixup(IDS_TRANSLATE_INFOBAR_ACCEPT)]; 414 [okButton_ setTitle:GetNSStringWithFixup(IDS_TRANSLATE_INFOBAR_ACCEPT)];
403 [cancelButton_ setTitle:GetNSStringWithFixup(IDS_TRANSLATE_INFOBAR_DENY)]; 415 [cancelButton_ setTitle:GetNSStringWithFixup(IDS_TRANSLATE_INFOBAR_DENY)];
404 416
405 // Set up "Show original" and "Try again" buttons. 417 // Set up "Show original" and "Try again" buttons.
406 [showOriginalButton_ setBezelStyle:NSRoundRectBezelStyle];
407 [showOriginalButton_ setFrame:okButtonFrame]; 418 [showOriginalButton_ setFrame:okButtonFrame];
408 [tryAgainButton_ setBezelStyle:NSRoundRectBezelStyle];
409 [tryAgainButton_ setFrame:okButtonFrame]; 419 [tryAgainButton_ setFrame:okButtonFrame];
410 420
421 // Set each of the buttons and popups to the NSTexturedRoundedBezelStyle
422 // (metal-looking) style.
423 NSArray* allControls = [self allControls];
424 for (NSControl* control in allControls) {
425 if (![control isKindOfClass:[NSButton class]])
426 continue;
427 NSButton* button = (NSButton*)control;
428 [button setBezelStyle:NSTexturedRoundedBezelStyle];
429 if ([button isKindOfClass:[NSPopUpButton class]]) {
430 [[button cell] setArrowPosition:NSPopUpArrowAtBottom];
431 }
432 }
433 // The options button is handled differently than the rest as it floats
434 // to the right.
435 [optionsPopUp_ setBezelStyle:NSTexturedRoundedBezelStyle];
436 [[optionsPopUp_ cell] setArrowPosition:NSPopUpArrowAtBottom];
437
411 [showOriginalButton_ setTarget:self]; 438 [showOriginalButton_ setTarget:self];
412 [showOriginalButton_ setAction:@selector(showOriginal:)]; 439 [showOriginalButton_ setAction:@selector(showOriginal:)];
413 [tryAgainButton_ setTarget:self]; 440 [tryAgainButton_ setTarget:self];
414 [tryAgainButton_ setAction:@selector(ok:)]; 441 [tryAgainButton_ setAction:@selector(ok:)];
415 442
416 [showOriginalButton_ 443 [showOriginalButton_
417 setTitle:GetNSStringWithFixup(IDS_TRANSLATE_INFOBAR_REVERT)]; 444 setTitle:GetNSStringWithFixup(IDS_TRANSLATE_INFOBAR_REVERT)];
418 [tryAgainButton_ 445 [tryAgainButton_
419 setTitle:GetNSStringWithFixup(IDS_TRANSLATE_INFOBAR_RETRY)]; 446 setTitle:GetNSStringWithFixup(IDS_TRANSLATE_INFOBAR_RETRY)];
420 447
421 // Add and configure controls that are visible in all modes. 448 // Add and configure controls that are visible in all modes.
422 [optionsPopUp_ setAutoresizingMask:NSViewMinXMargin | NSViewMinYMargin | 449 [optionsPopUp_ setAutoresizingMask:NSViewMinXMargin | NSViewMinYMargin |
423 NSViewMaxYMargin]; 450 NSViewMaxYMargin];
424 // Add "options" popup z-ordered below all other controls so when we 451 // Add "options" popup z-ordered below all other controls so when we
425 // resize the toolbar it doesn't hide them. 452 // resize the toolbar it doesn't hide them.
426 [infoBarView_ addSubview:optionsPopUp_ 453 [infoBarView_ addSubview:optionsPopUp_
427 positioned:NSWindowBelow 454 positioned:NSWindowBelow
428 relativeTo:nil]; 455 relativeTo:nil];
429 [GTMUILocalizerAndLayoutTweaker sizeToFitView:optionsPopUp_]; 456 [GTMUILocalizerAndLayoutTweaker sizeToFitView:optionsPopUp_];
430 MoveControl(closeButton_, optionsPopUp_, spaceBetweenControls_, false); 457 MoveControl(closeButton_, optionsPopUp_, spaceBetweenControls_, false);
431 VerticallyCenterView(optionsPopUp_); 458 VerticallyCenterView(optionsPopUp_);
432 459
460 [infoBarView_ setPostsFrameChangedNotifications:YES];
461 [[NSNotificationCenter defaultCenter]
462 addObserver:self
463 selector:@selector(didChangeFrame:)
464 name:NSViewFrameDidChangeNotification
465 object:infoBarView_];
433 // Show and place GUI elements. 466 // Show and place GUI elements.
434 [self updateState]; 467 [self updateState];
435 } 468 }
436 469
470 - (void)adjustOptionsButtonSizeAndVisibilityForView:(NSView*)lastView {
471 [optionsPopUp_ setHidden:NO];
472 [self rebuildOptionsMenu:NO];
473 [[optionsPopUp_ cell] setArrowPosition:NSPopUpArrowAtBottom];
474 [optionsPopUp_ sizeToFit];
475
476 MoveControl(closeButton_, optionsPopUp_, spaceBetweenControls_, false);
477 if (!VerifyControlOrderAndSpacing(lastView, optionsPopUp_)) {
478 [self rebuildOptionsMenu:YES];
479 NSRect oldFrame = [optionsPopUp_ frame];
480 oldFrame.size.width = NSHeight(oldFrame);
481 [optionsPopUp_ setFrame:oldFrame];
482 [[optionsPopUp_ cell] setArrowPosition:NSPopUpArrowAtCenter];
483 MoveControl(closeButton_, optionsPopUp_, spaceBetweenControls_, false);
484 if (!VerifyControlOrderAndSpacing(lastView, optionsPopUp_)) {
485 [optionsPopUp_ setHidden:YES];
486 }
487 }
488 }
489
437 // Called when "Translate" button is clicked. 490 // Called when "Translate" button is clicked.
438 - (IBAction)ok:(id)sender { 491 - (IBAction)ok:(id)sender {
439 TranslateInfoBarDelegate* delegate = [self delegate]; 492 TranslateInfoBarDelegate* delegate = [self delegate];
440 TranslateInfoBarDelegate::Type state = delegate->type(); 493 TranslateInfoBarDelegate::Type state = delegate->type();
441 DCHECK(state == TranslateInfoBarDelegate::kBeforeTranslate || 494 DCHECK(state == TranslateInfoBarDelegate::kBeforeTranslate ||
442 state == TranslateInfoBarDelegate::kTranslationError); 495 state == TranslateInfoBarDelegate::kTranslationError);
443 delegate->Translate(); 496 delegate->Translate();
444 UMA_HISTOGRAM_COUNTS("Translate.Translate", 1); 497 UMA_HISTOGRAM_COUNTS("Translate.Translate", 1);
445 } 498 }
446 499
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
480 int cmd = [item tag]; 533 int cmd = [item tag];
481 // Danger Will Robinson! : This call can release the infobar (e.g. invoking 534 // Danger Will Robinson! : This call can release the infobar (e.g. invoking
482 // "About Translate" can open a new tab). 535 // "About Translate" can open a new tab).
483 // Do not access member variables after this line! 536 // Do not access member variables after this line!
484 optionsMenuModel_->ExecuteCommand(cmd); 537 optionsMenuModel_->ExecuteCommand(cmd);
485 } else { 538 } else {
486 NOTREACHED(); 539 NOTREACHED();
487 } 540 }
488 } 541 }
489 542
543 - (void)dealloc {
544 [[NSNotificationCenter defaultCenter] removeObserver:self];
545 [super dealloc];
546 }
547
490 #pragma mark NSMenuDelegate 548 #pragma mark NSMenuDelegate
491 549
492 // Invoked by virtue of us being set as the delegate for the options menu. 550 // Invoked by virtue of us being set as the delegate for the options menu.
493 - (void)menuNeedsUpdate:(NSMenu *)menu { 551 - (void)menuNeedsUpdate:(NSMenu *)menu {
494 [self rebuildOptionsMenu]; 552 [self adjustOptionsButtonSizeAndVisibilityForView:
553 [[self visibleControls] lastObject]];
495 } 554 }
496 555
497 @end 556 @end
498 557
499 @implementation TranslateInfoBarControllerBase (TestingAPI) 558 @implementation TranslateInfoBarControllerBase (TestingAPI)
500 559
560 - (NSArray*)allControls {
561 return [NSArray arrayWithObjects:label1_.get(),fromLanguagePopUp_.get(),
562 label2_.get(), toLanguagePopUp_.get(), label3_.get(), okButton_,
563 cancelButton_, showOriginalButton_.get(), tryAgainButton_.get(),
564 nil];
565 }
566
501 - (NSMenu*)optionsMenu { 567 - (NSMenu*)optionsMenu {
502 return [optionsPopUp_ menu]; 568 return [optionsPopUp_ menu];
503 } 569 }
504 570
505 - (NSButton*)tryAgainButton { 571 - (NSButton*)tryAgainButton {
506 return tryAgainButton_.get(); 572 return tryAgainButton_.get();
507 } 573 }
508 574
509 - (bool)verifyLayout { 575 - (bool)verifyLayout {
510 // All the controls available to translate infobars, except the options popup. 576 // All the controls available to translate infobars, except the options popup.
511 // The options popup is shown/hidden instead of actually removed. This gets 577 // The options popup is shown/hidden instead of actually removed. This gets
512 // checked in the subclasses. 578 // checked in the subclasses.
513 NSArray* allControls = [NSArray arrayWithObjects:label1_.get(), 579 NSArray* allControls = [self allControls];
514 fromLanguagePopUp_.get(), label2_.get(), toLanguagePopUp_.get(),
515 label3_.get(), showOriginalButton_.get(), tryAgainButton_.get(), nil];
516 NSArray* visibleControls = [self visibleControls]; 580 NSArray* visibleControls = [self visibleControls];
517 581
518 // Step 1: Make sure control visibility is what we expect. 582 // Step 1: Make sure control visibility is what we expect.
519 for (NSUInteger i = 0; i < [allControls count]; ++i) { 583 for (NSUInteger i = 0; i < [allControls count]; ++i) {
520 id control = [allControls objectAtIndex:i]; 584 id control = [allControls objectAtIndex:i];
521 bool hasSuperView = [control superview]; 585 bool hasSuperView = [control superview];
522 bool expectedVisibility = [visibleControls containsObject:control]; 586 bool expectedVisibility = [visibleControls containsObject:control];
523 587
524 if (expectedVisibility != hasSuperView) { 588 if (expectedVisibility != hasSuperView) {
525 NSString *title = @""; 589 NSString *title = @"";
526 if ([control isKindOfClass:[NSPopUpButton class]]) { 590 if ([control isKindOfClass:[NSPopUpButton class]]) {
527 title = [[[control menu] itemAtIndex:0] title]; 591 title = [[[control menu] itemAtIndex:0] title];
528 } 592 }
529 593
530 LOG(ERROR) << 594 LOG(ERROR) <<
531 "State: " << [self description] << 595 "State: " << [self description] <<
532 " Control @" << i << (hasSuperView ? " has" : " doesn't have") << 596 " Control @" << i << (hasSuperView ? " has" : " doesn't have") <<
533 " a superview" << [[control description] UTF8String] << 597 " a superview" << [[control description] UTF8String] <<
534 " Title=" << [title UTF8String]; 598 " Title=" << [title UTF8String];
535 return false; 599 return false;
536 } 600 }
537 } 601 }
538 602
539 // Step 2: Check that controls are ordered correctly with no overlap. 603 // Step 2: Check that controls are ordered correctly with no overlap.
540 id previousControl = nil; 604 id previousControl = nil;
541 for (NSUInteger i = 0; i < [visibleControls count]; ++i) { 605 for (NSUInteger i = 0; i < [visibleControls count]; ++i) {
542 id control = [visibleControls objectAtIndex:i]; 606 id control = [visibleControls objectAtIndex:i];
607 // The options pop up doesn't lay out like the rest of the controls as
608 // it floats to the right. It has some known issues shown in
609 // http://crbug.com/47941.
610 if (control == optionsPopUp_.get())
611 continue;
543 if (previousControl && 612 if (previousControl &&
544 !VerifyControlOrderAndSpacing(previousControl, control)) { 613 !VerifyControlOrderAndSpacing(previousControl, control)) {
545 NSString *title = @""; 614 NSString *title = @"";
546 if ([control isKindOfClass:[NSPopUpButton class]]) { 615 if ([control isKindOfClass:[NSPopUpButton class]]) {
547 title = [[[control menu] itemAtIndex:0] title]; 616 title = [[[control menu] itemAtIndex:0] title];
548 } 617 }
549 LOG(ERROR) << 618 LOG(ERROR) <<
550 "State: " << [self description] << 619 "State: " << [self description] <<
551 " Control @" << i << " not ordered correctly: " << 620 " Control @" << i << " not ordered correctly: " <<
552 [[control description] UTF8String] <<[title UTF8String]; 621 [[control description] UTF8String] <<[title UTF8String];
553 return false; 622 return false;
554 } 623 }
555 previousControl = control; 624 previousControl = control;
556 } 625 }
557 626
558 return true; 627 return true;
559 } 628 }
560 629
561 @end // TranslateInfoBarControllerBase (TestingAPI) 630 @end // TranslateInfoBarControllerBase (TestingAPI)
562 631
OLDNEW
« no previous file with comments | « chrome/browser/cocoa/translate/translate_infobar_base.h ('k') | chrome/browser/cocoa/translate/translate_infobar_unittest.mm » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698