summaryrefslogtreecommitdiffstats
path: root/chrome/browser/cocoa/speech_input_window_controller.mm
blob: 1efb3f4ff73fe8e05c3844cd8167059b5ff98f40 (plain)
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
// Copyright (c) 2010 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 "speech_input_window_controller.h"

#include "app/l10n_util.h"
#include "app/resource_bundle.h"
#include "base/mac_util.h"
#include "base/sys_string_conversions.h"
#include "chrome/browser/cocoa/info_bubble_view.h"
#include "grit/generated_resources.h"
#include "grit/theme_resources.h"
#import "skia/ext/skia_utils_mac.h"
#import "third_party/GTM/AppKit/GTMUILocalizerAndLayoutTweaker.h"

const int kBubbleControlVerticalSpacing = 10;  // Space between controls.
const int kBubbleHorizontalMargin = 15;  // Space on either sides of controls.

@interface SpeechInputWindowController (Private)
- (NSSize)calculateContentSize;
- (void)layout:(NSSize)size;
@end

@implementation SpeechInputWindowController

- (id)initWithParentWindow:(NSWindow*)parentWindow
                  delegate:(SpeechInputBubbleDelegate*)delegate
              anchoredAt:(NSPoint)anchoredAt {
  anchoredAt.x -= info_bubble::kBubbleArrowXOffset +
                  info_bubble::kBubbleArrowWidth / 2.0;
  if ((self = [super initWithWindowNibPath:@"SpeechInputBubble"
                              parentWindow:parentWindow
                                anchoredAt:anchoredAt])) {
    DCHECK(delegate);
    delegate_ = delegate;

    [self showWindow:nil];
  }
  return self;
}

- (void)awakeFromNib {
  NSWindow* window = [self window];
  [[self bubble] setArrowLocation:info_bubble::kTopLeft];
  NSImage* icon = ResourceBundle::GetSharedInstance().GetNSImageNamed(
      IDR_SPEECH_INPUT_RECORDING);
  [iconImage_ setImage:icon];
  [iconImage_ setNeedsDisplay:YES];

  NSSize newSize = [self calculateContentSize];
  [[self bubble] setFrameSize:newSize];
  NSSize windowDelta = NSMakeSize(
      newSize.width - NSWidth([[window contentView] bounds]),
      newSize.height - NSHeight([[window contentView] bounds]));
  windowDelta = [[window contentView] convertSize:windowDelta toView:nil];
  NSRect newFrame = [window frame];
  newFrame.size.width += windowDelta.width;
  newFrame.size.height += windowDelta.height;
  [window setFrame:newFrame display:NO];

  [self layout:newSize];  // Layout all the child controls.
}

- (IBAction)cancel:(id)sender {
  delegate_->RecognitionCancelled();
}

// Calculate the window dimensions to reflect the sum height and max width of
// all controls, with appropriate spacing between and around them. The returned
// size is in view coordinates.
- (NSSize)calculateContentSize {
  [GTMUILocalizerAndLayoutTweaker sizeToFitView:cancelButton_];
  NSSize size = [cancelButton_ bounds].size;
  int newHeight = size.height + kBubbleControlVerticalSpacing;
  int newWidth = size.width;

  NSImage* icon = ResourceBundle::GetSharedInstance().GetNSImageNamed(
      IDR_SPEECH_INPUT_RECORDING);
  size = [icon size];
  newHeight += size.height + kBubbleControlVerticalSpacing;
  if (newWidth < size.width)
    newWidth = size.width;

  [GTMUILocalizerAndLayoutTweaker sizeToFitFixedWidthTextField:
      instructionLabel_];
  size = [instructionLabel_ bounds].size;
  newHeight += size.height;
  if (newWidth < size.width)
    newWidth = size.width;

  return NSMakeSize(newWidth + 2 * kBubbleHorizontalMargin,
                    newHeight + 2 * kBubbleControlVerticalSpacing);
}

// Position the controls within the given content area bounds.
- (void)layout:(NSSize)size {
  int y = kBubbleControlVerticalSpacing;

  NSRect rect = [cancelButton_ bounds];
  rect.origin.x = (size.width - rect.size.width) / 2;
  rect.origin.y = y;
  [cancelButton_ setFrame:rect];
  y += rect.size.height + kBubbleControlVerticalSpacing;

  rect = [iconImage_ bounds];
  rect.origin.x = (size.width - rect.size.width) / 2;
  rect.origin.y = y;
  [iconImage_ setFrame:rect];
  y += rect.size.height + kBubbleControlVerticalSpacing;

  rect = [instructionLabel_ bounds];
  rect.origin.x = (size.width - rect.size.width) / 2;
  rect.origin.y = y;
  [instructionLabel_ setFrame:rect];
}

- (void)didStartRecognition {
  NSImage* icon = ResourceBundle::GetSharedInstance().GetNSImageNamed(
      IDR_SPEECH_INPUT_PROCESSING);
  [iconImage_ setImage:icon];
  [iconImage_ setNeedsDisplay:YES];
}

- (void)windowWillClose:(NSNotification*)notification {
  delegate_->InfoBubbleClosed();
}

@end  // implementation SpeechInputWindowController