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

Side by Side Diff: chrome/browser/ui/cocoa/translate/translate_bubble_controller.mm

Issue 203223002: Translate bubble for Mac OS X (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 6 years, 9 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 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 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 "chrome/browser/ui/cocoa/translate/translate_bubble_controller.h" 5 #import "chrome/browser/ui/cocoa/translate/translate_bubble_controller.h"
6 6
7 #include "base/mac/foundation_util.h"
7 #include "base/mac/scoped_nsobject.h" 8 #include "base/mac/scoped_nsobject.h"
9 #include "base/strings/sys_string_conversions.h"
8 #include "chrome/browser/translate/translate_ui_delegate.h" 10 #include "chrome/browser/translate/translate_ui_delegate.h"
9 #import "chrome/browser/ui/cocoa/browser_window_controller.h" 11 #import "chrome/browser/ui/cocoa/browser_window_controller.h"
10 #import "chrome/browser/ui/cocoa/info_bubble_view.h" 12 #import "chrome/browser/ui/cocoa/info_bubble_view.h"
11 #import "chrome/browser/ui/cocoa/info_bubble_window.h" 13 #import "chrome/browser/ui/cocoa/info_bubble_window.h"
12 #import "chrome/browser/ui/cocoa/toolbar/toolbar_controller.h" 14 #import "chrome/browser/ui/cocoa/toolbar/toolbar_controller.h"
15 #include "chrome/browser/ui/translate/language_combobox_model.h"
13 #include "chrome/browser/ui/translate/translate_bubble_model_impl.h" 16 #include "chrome/browser/ui/translate/translate_bubble_model_impl.h"
17 #include "content/public/browser/browser_context.h"
18 #include "grit/generated_resources.h"
19 #include "third_party/google_toolbox_for_mac/src/AppKit/GTMUILocalizerAndLayoutT weaker.h"
20 #import "ui/base/cocoa/controls/hyperlink_button_cell.h"
14 #import "ui/base/cocoa/flipped_view.h" 21 #import "ui/base/cocoa/flipped_view.h"
15 #import "ui/base/cocoa/window_size_constants.h" 22 #import "ui/base/cocoa/window_size_constants.h"
23 #include "ui/base/l10n/l10n_util.h"
24 #include "ui/base/models/combobox_model.h"
25
26 namespace {
27
28 enum ButtonId {
29 kButtonIdTranslate,
30 kButtonIdNope,
31 kButtonIdDone,
32 kButtonIdCancel,
33 kButtonIdShowOriginal,
34 kButtonIdTryAgain,
35 kButtonIdAlwaysTranslate,
36 kButtonIdLinkAdvanced,
37 };
38
39 enum PopUpButtonId {
40 kPopUpButtonIdDenial,
41 kPopUpButtonIdSourceLanguage,
42 kPopUpButtonIdTargetLanguage,
43 };
44
45 } // namespace
46
47 class TranslateDenialComboboxModel : public ui::ComboboxModel {
48 public:
49 enum {
50 kIndexNope = 1,
51 kIndexNeverTranslateLanguage = 2,
52 kIndexNeverTranslateSite = 3,
53 };
54
55 explicit TranslateDenialComboboxModel(
56 const base::string16& original_language_name) {
57 // Dummy menu item, which is shown on the top of a NSPopUpButton. The top
58 // text of the denial pop up menu should be IDS_TRANSLATE_BUBBLE_DENY, while
59 // it is impossible to use it here because NSPopUpButtons' addItemWithTitle
60 // removes a duplicated menu item. Instead, the title will be set later by
61 // NSMenuItem's setTitle.
62 items_.push_back(base::string16());
63
64 // Menu items in the drop down menu.
65 items_.push_back(l10n_util::GetStringUTF16(IDS_TRANSLATE_BUBBLE_DENY));
66 items_.push_back(l10n_util::GetStringFUTF16(
67 IDS_TRANSLATE_BUBBLE_NEVER_TRANSLATE_LANG,
68 original_language_name));
69 items_.push_back(l10n_util::GetStringUTF16(
70 IDS_TRANSLATE_BUBBLE_NEVER_TRANSLATE_SITE));
71 }
72 virtual ~TranslateDenialComboboxModel() {}
73
74 private:
75 // ComboboxModel:
76 virtual int GetItemCount() const OVERRIDE {
77 return items_.size();
78 }
79 virtual base::string16 GetItemAt(int index) OVERRIDE {
80 return items_[index];
81 }
82 virtual bool IsItemSeparatorAt(int index) OVERRIDE {
83 return false;
84 }
85 virtual int GetDefaultIndex() const OVERRIDE {
86 return 0;
87 }
88
89 std::vector<base::string16> items_;
90
91 DISALLOW_COPY_AND_ASSIGN(TranslateDenialComboboxModel);
92 };
93
94 const CGFloat kWindowWidth = 320;
95
96 // Padding between the window frame and content.
97 const CGFloat kFramePadding = 16;
98
99 const CGFloat kRelatedControlHorizontalSpacing = -2;
100
101 const CGFloat kRelatedControlVerticalSpacing = 4;
102 const CGFloat kUnrelatedControlVerticalSpacing = 20;
16 103
17 @implementation TranslateBubbleController 104 @implementation TranslateBubbleController
18 105
19 - (id)initWithParentWindow:(BrowserWindowController*)controller 106 - (id)initWithParentWindow:(BrowserWindowController*)controller
20 model:(scoped_ptr<TranslateBubbleModel>)model 107 model:(scoped_ptr<TranslateBubbleModel>)model
21 webContents:(content::WebContents*)webContents { 108 webContents:(content::WebContents*)webContents {
22 NSWindow* parentWindow = [controller window]; 109 NSWindow* parentWindow = [controller window];
23 110
24 // Use an arbitrary size; it will be changed in performLayout. 111 // Use an arbitrary size; it will be changed in performLayout.
25 NSRect contentRect = ui::kWindowSizeDeterminedLater; 112 NSRect contentRect = ui::kWindowSizeDeterminedLater;
26 base::scoped_nsobject<InfoBubbleWindow> window( 113 base::scoped_nsobject<InfoBubbleWindow> window(
27 [[InfoBubbleWindow alloc] initWithContentRect:contentRect 114 [[InfoBubbleWindow alloc] initWithContentRect:contentRect
28 styleMask:NSBorderlessWindowMask 115 styleMask:NSBorderlessWindowMask
29 backing:NSBackingStoreBuffered 116 backing:NSBackingStoreBuffered
30 defer:NO]); 117 defer:NO]);
31 118
32 if ((self = [super initWithWindow:window 119 if ((self = [super initWithWindow:window
33 parentWindow:parentWindow 120 parentWindow:parentWindow
34 anchoredAt:NSZeroPoint])) { 121 anchoredAt:NSZeroPoint])) {
35 webContents_ = webContents; 122 webContents_ = webContents;
36 model_ = model.Pass(); 123 model_ = model.Pass();
37 if (model_->GetViewState() != 124 if (model_->GetViewState() !=
38 TranslateBubbleModel::VIEW_STATE_BEFORE_TRANSLATE) { 125 TranslateBubbleModel::VIEW_STATE_BEFORE_TRANSLATE) {
39 translateExecuted_ = YES; 126 translateExecuted_ = YES;
40 } 127 }
41 128
129 // Create the container view that uses flipped coordinates.
130 CGFloat x = info_bubble::kBubbleCornerRadius;
131 CGFloat y = -info_bubble::kBubbleCornerRadius;
132 NSRect contentFrame = NSMakeRect(x, y, kWindowWidth, 1);
133 NSView* contentView = [[FlippedView alloc] initWithFrame:contentFrame];
groby-ooo-7-16 2014/03/18 17:58:18 Why not just replace contentView, if you need a Fl
hajimehoshi 2014/03/19 07:33:22 Done (Removed).
134 [[window contentView] setSubviews:@[contentView]];
135
136 beforeTranslateView_.reset([self createViewBeforeTranslate]);
137 translatingView_.reset([self createViewTranslating]);
138 afterTranslateView_.reset([self createViewAfterTranslate]);
139 errorView_.reset([self createViewError]);
140 advancedView_.reset([self createViewAdvanced]);
141
42 [self performLayout]; 142 [self performLayout];
43 } 143 }
44 return self; 144 return self;
45 } 145 }
46 146
47 @synthesize webContents = webContents_; 147 @synthesize webContents = webContents_;
48 148
149 - (NSView*)currentView {
150 switch (model_->GetViewState()) {
151 case TranslateBubbleModel::VIEW_STATE_BEFORE_TRANSLATE:
152 return beforeTranslateView_;
153 case TranslateBubbleModel::VIEW_STATE_TRANSLATING:
154 return translatingView_;
155 case TranslateBubbleModel::VIEW_STATE_AFTER_TRANSLATE:
156 return afterTranslateView_;
157 case TranslateBubbleModel::VIEW_STATE_ERROR:
158 return errorView_;
159 case TranslateBubbleModel::VIEW_STATE_ADVANCED:
160 return advancedView_;
161 }
162 NOTREACHED();
163 return nil;
164 }
165
49 - (const TranslateBubbleModel*)model { 166 - (const TranslateBubbleModel*)model {
50 return model_.get(); 167 return model_.get();
51 } 168 }
52 169
53 - (void)showWindow:(id)sender { 170 - (void)showWindow:(id)sender {
54 BrowserWindowController* controller = [[self parentWindow] windowController]; 171 BrowserWindowController* controller = [[self parentWindow] windowController];
55 NSPoint anchorPoint = [[controller toolbarController] translateBubblePoint]; 172 NSPoint anchorPoint = [[controller toolbarController] translateBubblePoint];
56 anchorPoint = [[self parentWindow] convertBaseToScreen:anchorPoint]; 173 anchorPoint = [[self parentWindow] convertBaseToScreen:anchorPoint];
57 [self setAnchorPoint:anchorPoint]; 174 [self setAnchorPoint:anchorPoint];
58 [super showWindow:sender]; 175 [super showWindow:sender];
59 } 176 }
60 177
61 - (void)switchView:(TranslateBubbleModel::ViewState)viewState { 178 - (void)switchView:(TranslateBubbleModel::ViewState)viewState {
62 if (model_->GetViewState() == viewState) 179 if (model_->GetViewState() == viewState)
63 return; 180 return;
64 181
65 model_->SetViewState(viewState); 182 model_->SetViewState(viewState);
66 [self performLayout]; 183 [self performLayout];
67 } 184 }
68 185
69 - (void)switchToErrorView:(TranslateErrors::Type)errorType { 186 - (void)switchToErrorView:(TranslateErrors::Type)errorType {
70 // TODO(hajimehoshi): Implement this. 187 // TODO(hajimehoshi): Implement this.
71 } 188 }
72 189
73 - (void)performLayout { 190 - (void)performLayout {
74 // TODO(hajimehoshi): Now this shows just an empty bubble. Implement this. 191 NSView* subview = [[[[self window] contentView] subviews] objectAtIndex:0];
groby-ooo-7-16 2014/03/18 17:58:18 It might be worth storing that object on the contr
hajimehoshi 2014/03/19 07:33:22 Done.
75 [[self window] display]; 192 [subview setSubviews:@[[self currentView]]];
groby-ooo-7-16 2014/03/18 17:58:18 nit - @[] has spaces after/before bracket. I.e. @[
hajimehoshi 2014/03/19 07:33:22 Done.
193
194 CGFloat height = NSHeight([[self currentView] frame]) +
195 2 * kFramePadding + info_bubble::kBubbleArrowHeight;
196
197 NSRect subviewFrame = [subview frame];
198 subviewFrame.size.height = height;
199 [subview setFrame:subviewFrame];
200
201 NSRect windowFrame = [[self window] frame];
202 windowFrame.origin.y += NSHeight(windowFrame) - height;
203 windowFrame.size.width = kWindowWidth;
204 windowFrame.size.height = height;
205 [[self window] setFrame:windowFrame
206 display:YES
207 animate:[[self window] isVisible]];
208 }
209
210 - (NSView*)createViewBeforeTranslate {
211 CGFloat contentWidth = kWindowWidth - 2 * kFramePadding;
212 NSRect contentFrame = NSMakeRect(
213 kFramePadding,
214 kFramePadding + info_bubble::kBubbleArrowHeight,
215 contentWidth,
216 1);
217 NSView* view = [[FlippedView alloc] initWithFrame:contentFrame];
groby-ooo-7-16 2014/03/18 17:58:18 In general, if you can avoid FlippedView, I would.
hajimehoshi 2014/03/19 07:33:22 Done.
218
219 NSString* message =
220 l10n_util::GetNSStringWithFixup(IDS_TRANSLATE_BUBBLE_BEFORE_TRANSLATE);
221 NSTextField* textLabel = [self addText:message
222 withSize:[NSFont smallSystemFontSize]
223 bold:NO
224 toView:view
225 atPoint:NSZeroPoint];
226 message = l10n_util::GetNSStringWithFixup(IDS_TRANSLATE_BUBBLE_ADVANCED);
227 NSButton* advancedLinkButton =
228 [self addLinkButtonWithText:message
229 tag:kButtonIdLinkAdvanced
230 toView:view
231 atPoint:NSZeroPoint];
232
233 NSString* title =
234 l10n_util::GetNSStringWithFixup(IDS_TRANSLATE_BUBBLE_ACCEPT);
235 NSButton* translateButton =
236 [self addButton:title
237 withTag:kButtonIdTranslate
238 toView:view
239 atPoint:NSZeroPoint];
240
241 base::string16 originalLanguageName =
242 model_->GetLanguageNameAt(model_->GetOriginalLanguageIndex());
243 translateDenialComboboxModel_.reset(
244 new TranslateDenialComboboxModel(originalLanguageName));
245 NSPopUpButton* denyPopUpButton =
246 [self addPopUpButton:translateDenialComboboxModel_.get()
247 withTag:kPopUpButtonIdDenial
248 toView:view
249 atPoint:NSZeroPoint];
250 [denyPopUpButton setPullsDown:YES];
251 title = base::SysUTF16ToNSString(
252 l10n_util::GetStringUTF16(IDS_TRANSLATE_BUBBLE_DENY));
253 [[denyPopUpButton itemAtIndex:0] setTitle:title];
254
255 // Adjust width for the first item.
256 std::vector<NSString*> titles;
257 for (int i = 1; i < [denyPopUpButton numberOfItems]; i++) {
258 NSMenuItem* item = [denyPopUpButton itemAtIndex:i];
259 titles.push_back([item title]);
260 [item setTitle:@""];
261 }
262 [denyPopUpButton sizeToFit];
263 for (int i = 1; i < [denyPopUpButton numberOfItems]; i++) {
264 NSMenuItem* item = [denyPopUpButton itemAtIndex:i];
265 [item setTitle:titles[i-1]];
266 }
267
268 // Layout
269 CGFloat yPos = 0;
270
271 NSRect advancedLinkButtonFrame = [advancedLinkButton frame];
272 advancedLinkButtonFrame.origin.x = NSWidth([textLabel frame]);
273 [advancedLinkButton setFrame:advancedLinkButtonFrame];
274
275 yPos += NSHeight([textLabel frame]);
276 yPos += kUnrelatedControlVerticalSpacing;
277
278 NSRect translateButtonFrame = [translateButton frame];
279 translateButtonFrame.origin.x =
280 contentWidth - NSWidth([translateButton frame]);
281 translateButtonFrame.origin.y = yPos;
282 [translateButton setFrame:translateButtonFrame];
283
284 NSRect denyPopUpButtonFrame = [denyPopUpButton frame];
285 CGFloat diffY = [[denyPopUpButton cell]
286 titleRectForBounds:[denyPopUpButton bounds]].origin.y;
287 denyPopUpButtonFrame.origin.x =
288 NSMinX([translateButton frame]) - denyPopUpButtonFrame.size.width
289 - kRelatedControlHorizontalSpacing;
290 denyPopUpButtonFrame.origin.y = yPos + diffY;
291 [denyPopUpButton setFrame:denyPopUpButtonFrame];
292
293 yPos += NSHeight([translateButton frame]);
294
295 contentFrame = [view frame];
296 contentFrame.size.height = yPos;
297 [view setFrame:contentFrame];
298
299 return view;
300 }
301
302 - (NSView*)createViewTranslating {
303 CGFloat contentWidth = kWindowWidth - 2 * kFramePadding;
304 NSRect contentFrame = NSMakeRect(
305 kFramePadding,
306 kFramePadding + info_bubble::kBubbleArrowHeight,
307 contentWidth,
308 1);
309 NSView* view = [[FlippedView alloc] initWithFrame:contentFrame];
310
311 CGFloat yPos = 0;
312
313 NSString* message =
314 l10n_util::GetNSStringWithFixup(IDS_TRANSLATE_BUBBLE_TRANSLATING);
315 NSTextField* textLabel = [self addText:message
316 withSize:[NSFont smallSystemFontSize]
317 bold:NO
318 toView:view
319 atPoint:NSMakePoint(0, yPos)];
320 yPos += NSHeight([textLabel frame]);
321 yPos += kUnrelatedControlVerticalSpacing;
322
323 NSString* title =
324 l10n_util::GetNSStringWithFixup(IDS_TRANSLATE_BUBBLE_REVERT);
325 NSButton* showOriginalButton =
326 [self addButton:title
327 withTag:kButtonIdShowOriginal
328 toView:view
329 atPoint:NSMakePoint(0, yPos)];
330 [showOriginalButton setEnabled:NO];
331 NSRect showOriginalButtonFrame = [showOriginalButton frame];
332 showOriginalButtonFrame.origin.x =
333 contentWidth - NSWidth([showOriginalButton frame]);
334 [showOriginalButton setFrame:showOriginalButtonFrame];
335
336 yPos += NSHeight([showOriginalButton frame]);
337
338 contentFrame = [view frame];
339 contentFrame.size.height = yPos;
340 [view setFrame:contentFrame];
341
342 return view;
343 }
344
345 - (NSView*)createViewAfterTranslate {
346 CGFloat contentWidth = kWindowWidth - 2 * kFramePadding;
347 NSRect contentFrame = NSMakeRect(
348 kFramePadding,
349 kFramePadding + info_bubble::kBubbleArrowHeight,
350 contentWidth,
351 1);
352 NSView* view = [[FlippedView alloc] initWithFrame:contentFrame];
353
354 CGFloat yPos = 0;
355
356 NSString* message =
357 l10n_util::GetNSStringWithFixup(IDS_TRANSLATE_BUBBLE_TRANSLATED);
358 NSTextField* textLabel = [self addText:message
359 withSize:[NSFont smallSystemFontSize]
360 bold:NO
361 toView:view
362 atPoint:NSMakePoint(0, yPos)];
363 message = l10n_util::GetNSStringWithFixup(IDS_TRANSLATE_BUBBLE_ADVANCED);
364 [self addLinkButtonWithText:message
365 tag:kButtonIdLinkAdvanced
366 toView:view
367 atPoint:NSMakePoint(NSWidth([textLabel frame]), yPos)];
368 yPos += NSHeight([textLabel frame]);
369 yPos += kUnrelatedControlVerticalSpacing;
370
371 NSString* title =
372 l10n_util::GetNSStringWithFixup(IDS_TRANSLATE_BUBBLE_REVERT);
373 NSButton* showOriginalButton =
374 [self addButton:title
375 withTag:kButtonIdShowOriginal
376 toView:view
377 atPoint:NSMakePoint(0, yPos)];
378 NSRect showOriginalButtonFrame = [showOriginalButton frame];
379 showOriginalButtonFrame.origin.x =
380 contentWidth - NSWidth([showOriginalButton frame]);
381 [showOriginalButton setFrame:showOriginalButtonFrame];
382
383 yPos += NSHeight([showOriginalButton frame]);
384
385 contentFrame = [view frame];
386 contentFrame.size.height = yPos;
387 [view setFrame:contentFrame];
388
389 return view;
390 }
391
392 - (NSView*)createViewError {
393 CGFloat contentWidth = kWindowWidth - 2 * kFramePadding;
394 NSRect contentFrame = NSMakeRect(
395 kFramePadding,
396 kFramePadding + info_bubble::kBubbleArrowHeight,
397 contentWidth,
398 1);
399 NSView* view = [[FlippedView alloc] initWithFrame:contentFrame];
400
401 // TODO(hajimehoshi): Implement this.
402
403 return view;
404 }
405
406 - (NSView*)createViewAdvanced {
407 CGFloat contentWidth = kWindowWidth - 2 * kFramePadding;
408 NSRect contentFrame = NSMakeRect(
409 kFramePadding,
410 kFramePadding + info_bubble::kBubbleArrowHeight,
411 contentWidth,
412 1);
413 NSView* view = [[FlippedView alloc] initWithFrame:contentFrame];
414
415 NSString* title = l10n_util::GetNSStringWithFixup(
416 IDS_TRANSLATE_BUBBLE_PAGE_LANGUAGE);
417 NSTextField* sourceLanguageLabel = [self addText:title
418 withSize:[NSFont smallSystemFontSize]
419 bold:NO
420 toView:view
421 atPoint:NSZeroPoint];
422 title = l10n_util::GetNSStringWithFixup(
423 IDS_TRANSLATE_BUBBLE_TRANSLATION_LANGUAGE);
424 NSTextField* targetLanguageLabel = [self addText:title
425 withSize:[NSFont smallSystemFontSize]
426 bold:NO
427 toView:view
428 atPoint:NSZeroPoint];
429
430 // combobox
431 int sourceDefaultIndex = model_->GetOriginalLanguageIndex();
432 int targetDefaultIndex = model_->GetTargetLanguageIndex();
433 sourceLanguageComboboxModel_.reset(
434 new LanguageComboboxModel(sourceDefaultIndex, model_.get()));
435 targetLanguageComboboxModel_.reset(
436 new LanguageComboboxModel(targetDefaultIndex, model_.get()));
437 NSPopUpButton* sourcePopUpButton =
438 [self addPopUpButton:sourceLanguageComboboxModel_.get()
439 withTag:kPopUpButtonIdSourceLanguage
440 toView:view
441 atPoint:NSZeroPoint];
442 NSPopUpButton* targetPopUpButton =
443 [self addPopUpButton:targetLanguageComboboxModel_.get()
444 withTag:kPopUpButtonIdTargetLanguage
445 toView:view
446 atPoint:NSZeroPoint];
447
448 // 'Always translate' checkbox
449 BOOL isIncognitoWindow = webContents_ ?
450 webContents_->GetBrowserContext()->IsOffTheRecord() : NO;
451 if (!isIncognitoWindow) {
452 NSString* title =
453 l10n_util::GetNSStringWithFixup(IDS_TRANSLATE_BUBBLE_ALWAYS);
454 alwaysTranslateCheckbox_ =
455 [self addCheckbox:title
456 withTag:kButtonIdAlwaysTranslate
457 toView:view
458 atPoint:NSZeroPoint];
459 }
460
461 // Buttons
462 advancedDoneButton_ =
463 [self addButton:l10n_util::GetNSStringWithFixup(IDS_DONE)
464 withTag:kButtonIdDone
465 toView:view
466 atPoint:NSZeroPoint];
467 advancedCancelButton_ =
468 [self addButton:l10n_util::GetNSStringWithFixup(IDS_CANCEL)
469 withTag:kButtonIdCancel
470 toView:view
471 atPoint:NSZeroPoint];
472
473 // Layout
474 CGFloat textLabelWidth = NSWidth([sourceLanguageLabel frame]);
475 if (textLabelWidth < NSWidth([targetLanguageLabel frame]))
476 textLabelWidth = NSWidth([targetLanguageLabel frame]);
477
478 CGFloat yPos = 0;
479 CGFloat diffY = [[sourcePopUpButton cell]
480 titleRectForBounds:[sourcePopUpButton bounds]].origin.y;
481 NSRect frame = [sourceLanguageLabel frame];
482 frame.origin.x = textLabelWidth - NSWidth([sourceLanguageLabel frame]);
483 frame.origin.y = yPos + diffY;
484 [sourceLanguageLabel setFrame:frame];
485
486 frame = [sourcePopUpButton frame];
487 frame.origin.x = textLabelWidth;
488 frame.origin.y = yPos;
489 frame.size.width = (kWindowWidth - 2 * kFramePadding) - textLabelWidth;
490 [sourcePopUpButton setFrame:frame];
491
492 yPos += NSHeight([sourcePopUpButton frame]);
493 yPos += kRelatedControlVerticalSpacing;
494
495 frame = [targetLanguageLabel frame];
496 frame.origin.x = textLabelWidth - NSWidth([targetLanguageLabel frame]);
497 frame.origin.y = yPos + diffY;
498 [targetLanguageLabel setFrame:frame];
499
500 frame = [targetPopUpButton frame];
501 frame.origin.x = textLabelWidth;
502 frame.origin.y = yPos;
503 frame.size.width = (kWindowWidth - 2 * kFramePadding) - textLabelWidth;
504 [targetPopUpButton setFrame:frame];
505
506 yPos += NSHeight([targetPopUpButton frame]);
507
508 if (alwaysTranslateCheckbox_) {
509 yPos += kRelatedControlVerticalSpacing;
510
511 NSRect frame = [alwaysTranslateCheckbox_ frame];
512 frame.origin.x = textLabelWidth;
513 frame.origin.y = yPos;
514 [alwaysTranslateCheckbox_ setFrame:frame];
515
516 yPos += NSHeight([alwaysTranslateCheckbox_ frame]);
517 }
518
519 yPos += kUnrelatedControlVerticalSpacing;
520
521 frame = [advancedDoneButton_ frame];
522 frame.origin.y = yPos;
523 [advancedDoneButton_ setFrame:frame];
524
525 frame = [advancedCancelButton_ frame];
526 frame.origin.y = yPos;
527 [advancedCancelButton_ setFrame:frame];
528
529 yPos += NSHeight([advancedDoneButton_ frame]);
530
531 contentFrame = [view frame];
532 contentFrame.size.height = yPos;
533 [view setFrame:contentFrame];
534
535 [self updateAdvancedView];
536
537 return view;
538 }
539
540 - (void)updateAdvancedView {
groby-ooo-7-16 2014/03/18 17:58:18 I think it might be clearer to subclass NSView for
hajimehoshi 2014/03/19 07:33:22 Nothing special. I wasn't able to find such bubble
541 if (alwaysTranslateCheckbox_) {
542 NSInteger state = model_->ShouldAlwaysTranslate() ? NSOnState : NSOffState;
543 [alwaysTranslateCheckbox_ setState:state];
544 }
545
546 NSString* title;
547 if (model_->IsPageTranslatedInCurrentLanguages())
548 title = l10n_util::GetNSStringWithFixup(IDS_DONE);
549 else
550 title = l10n_util::GetNSStringWithFixup(IDS_TRANSLATE_BUBBLE_ACCEPT);
551 [advancedDoneButton_ setTitle:title];
552 [advancedDoneButton_ sizeToFit];
553
554 NSRect frame = [advancedDoneButton_ frame];
555 frame.origin.x = (kWindowWidth - 2 * kFramePadding) - frame.size.width;
556 [advancedDoneButton_ setFrame:frame];
557
558 frame = [advancedCancelButton_ frame];
559 frame.origin.x = NSMinX([advancedDoneButton_ frame]) - frame.size.width
560 - kRelatedControlHorizontalSpacing;
561 [advancedCancelButton_ setFrame:frame];
562 }
563
564 // Create a new text field and add it to the given array of subviews.
565 // The array will retain a reference to the object.
566 - (NSTextField*)addText:(NSString*)text
567 withSize:(CGFloat)fontSize
568 bold:(BOOL)bold
569 toView:(NSView*)view
570 atPoint:(NSPoint)point {
571 CGFloat width = NSWidth([view frame]) - point.x;
572 NSRect frame = NSMakeRect(point.x, point.y, width, 100);
573 base::scoped_nsobject<NSTextField> textField(
574 [[NSTextField alloc] initWithFrame:frame]);
575 [textField setEditable:NO];
576 [textField setSelectable:YES];
577 [textField setDrawsBackground:NO];
578 [textField setBezeled:NO];
579 [textField setStringValue:text];
580 NSFont* font = bold ? [NSFont boldSystemFontOfSize:fontSize]
581 : [NSFont systemFontOfSize:fontSize];
582 [textField setFont:font];
583
584 frame = [textField frame];
585 frame.size.height +=
586 [GTMUILocalizerAndLayoutTweaker sizeToFitFixedWidthTextField:
587 textField];
588 [textField setFrame:frame];
589
590 [textField setAutoresizingMask:NSViewWidthSizable];
591 [view addSubview:textField.get()];
592
593 [textField sizeToFit];
594 return textField.get();
595 }
596
597 - (NSButton*)addLinkButtonWithText:(NSString*)text
598 tag:(NSInteger)tag
599 toView:(NSView*)view
600 atPoint:(NSPoint)point {
601 base::scoped_nsobject<NSButton> button(
602 [[NSButton alloc] initWithFrame:NSZeroRect]);
603 [button setTag:tag];
604 base::scoped_nsobject<HyperlinkButtonCell> cell(
605 [[HyperlinkButtonCell alloc] initTextCell:text]);
606 [cell setControlSize:NSSmallControlSize];
607 [button setCell:cell.get()];
608
609 [button setButtonType:NSMomentaryPushInButton];
610 [button setBezelStyle:NSRegularSquareBezelStyle];
611 [button sizeToFit];
612 NSRect frame = NSMakeRect(
613 point.x, point.y,
614 NSWidth([button frame]), NSHeight([button frame]));
615 [button setFrame:frame];
groby-ooo-7-16 2014/03/18 17:58:18 see below for setFrameOrigin:
hajimehoshi 2014/03/19 07:33:22 Done.
616 [button setAction:@selector(handleButtonPressed:)];
617 [button setTarget:self];
618
619 [view addSubview:button.get()];
620
621 return button.get();
622 }
623
624 - (NSButton*)addButton:(NSString*)title
625 withTag:(NSInteger)tag
626 toView:(NSView*)view
627 atPoint:(NSPoint)point {
628 base::scoped_nsobject<NSButton> button(
629 [[NSButton alloc] initWithFrame:NSZeroRect]);
630 [button setFont:[NSFont systemFontOfSize:[NSFont smallSystemFontSize]]];
631 [button setTag:tag];
632 [button setTitle:title];
633 [button setBezelStyle:NSRoundedBezelStyle];
634 [[button cell] setControlSize:NSSmallControlSize];
635 [button sizeToFit];
636 NSRect frame = NSMakeRect(
groby-ooo-7-16 2014/03/18 17:58:18 I think the next 4 lines (until -setFrame:) might
hajimehoshi 2014/03/19 07:33:22 Done.
637 point.x, point.y,
638 NSWidth([button frame]), NSHeight([button frame]));
639 [button setFrame:frame];
640 [button setAction:@selector(handleButtonPressed:)];
641 [button setTarget:self];
642
643 [view addSubview:button.get()];
644
645 return button.get();
646 }
647
648 - (NSButton*)addCheckbox:(NSString*)title
649 withTag:(NSInteger)tag
650 toView:(NSView*)view
651 atPoint:(NSPoint)point {
652 base::scoped_nsobject<NSButton> button(
653 [[NSButton alloc] initWithFrame:NSZeroRect]);
654 [button setFont:[NSFont systemFontOfSize:[NSFont smallSystemFontSize]]];
655 [button setTag:tag];
656 [button setTitle:title];
657 [[button cell] setControlSize:NSSmallControlSize];
658 [button setButtonType:NSSwitchButton];
659 [button sizeToFit];
660 NSRect frame = NSMakeRect(
661 point.x, point.y,
662 NSWidth([button frame]), NSHeight([button frame]));
663 [button setFrame:frame];
groby-ooo-7-16 2014/03/18 17:58:18 setFrameOrigin:, as above
hajimehoshi 2014/03/19 07:33:22 Done.
664 [button setAction:@selector(handleButtonPressed:)];
665 [button setTarget:self];
666
667 [view addSubview:button.get()];
668
669 return button.get();
670 }
671
672 - (NSPopUpButton*)addPopUpButton:(ui::ComboboxModel*)model
673 withTag:(NSInteger)tag
674 toView:(NSView*)view
675 atPoint:(NSPoint)point {
676 base::scoped_nsobject<NSPopUpButton> button(
677 [[NSPopUpButton alloc] initWithFrame:NSZeroRect pullsDown:NO]);
678 [button setFont:[NSFont systemFontOfSize:[NSFont smallSystemFontSize]]];
679 [button setBordered:YES];
680 [[button cell] setControlSize:NSSmallControlSize];
681 [button setTag:tag];
682 [button setAction:@selector(handlePopUpButtonSelectedItemChanged:)];
683 [button setTarget:self];
684
685 for (int i = 0; i < model->GetItemCount(); ++i)
686 [button addItemWithTitle:base::SysUTF16ToNSString(model->GetItemAt(i))];
687 [button selectItemAtIndex:model->GetDefaultIndex()];
688
689 [button sizeToFit];
690 NSRect frame = NSMakeRect(
691 point.x, point.y, NSWidth([button frame]), NSHeight([button frame]));
692 [button setFrame:frame];
693
694 [view addSubview:button.get()];
695
696 return button.get();
697 }
698
699 - (void)handleButtonPressed:(id)sender {
700 NSButton* button = base::mac::ObjCCastStrict<NSButton>(sender);
groby-ooo-7-16 2014/03/18 17:58:18 Is there a contraint that requires a switch based
hajimehoshi 2014/03/19 07:33:22 Done.
701 NSInteger tag = [button tag];
702 switch (tag) {
703 case kButtonIdTranslate: {
704 translateExecuted_ = YES;
705 model_->Translate();
706 break;
707 }
708 case kButtonIdNope: {
709 [self close];
710 break;
711 }
712 case kButtonIdDone: {
713 if (alwaysTranslateCheckbox_) {
714 model_->SetAlwaysTranslate(
715 [alwaysTranslateCheckbox_ state] == NSOnState);
716 }
717 if (model_->IsPageTranslatedInCurrentLanguages()) {
718 model_->GoBackFromAdvanced();
719 [self performLayout];
720 } else {
721 translateExecuted_ = true;
722 model_->Translate();
723 [self switchView:TranslateBubbleModel::VIEW_STATE_TRANSLATING];
724 }
725 break;
726 }
727 case kButtonIdCancel: {
728 model_->GoBackFromAdvanced();
729 [self performLayout];
730 break;
731 }
732 case kButtonIdShowOriginal: {
733 model_->RevertTranslation();
734 [self close];
735 break;
736 }
737 case kButtonIdLinkAdvanced: {
738 [self switchView:TranslateBubbleModel::VIEW_STATE_ADVANCED];
739 break;
740 }
741 case kButtonIdAlwaysTranslate: {
742 // Do nothing. The state of the checkbox affects only when the 'Done'
743 // button is pressed.
groby-ooo-7-16 2014/03/18 17:58:18 Can you simply not have an action for the checkbox
hajimehoshi 2014/03/19 07:33:22 Done.
744 break;
745 }
746 default:
747 break;
748 }
749 }
750
751 - (void)handlePopUpButtonSelectedItemChanged:(id)sender {
groby-ooo-7-16 2014/03/18 17:58:18 As for the button delegate, I'd much prefer a sepa
hajimehoshi 2014/03/19 07:33:22 Done.
752 NSPopUpButton* button = base::mac::ObjCCastStrict<NSPopUpButton>(sender);
753 NSInteger tag = [button tag];
754 switch (tag) {
755 case kPopUpButtonIdDenial: {
756 switch ([button indexOfSelectedItem]) {
757 case TranslateDenialComboboxModel::kIndexNope:
758 break;
759 case TranslateDenialComboboxModel::kIndexNeverTranslateLanguage:
760 model_->SetNeverTranslateLanguage(true);
761 break;
762 case TranslateDenialComboboxModel::kIndexNeverTranslateSite:
763 model_->SetNeverTranslateSite(true);
764 break;
765 }
766 [self close];
767 break;
768 }
769 case kPopUpButtonIdSourceLanguage: {
770 model_->UpdateOriginalLanguageIndex([button indexOfSelectedItem]);
771 [self updateAdvancedView];
772 break;
773 }
774 case kPopUpButtonIdTargetLanguage: {
775 model_->UpdateTargetLanguageIndex([button indexOfSelectedItem]);
776 [self updateAdvancedView];
777 break;
778 }
779 }
76 } 780 }
77 781
78 @end 782 @end
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698