• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1// Copyright (c) 2011 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 <Cocoa/Cocoa.h>
6
7#include "chrome/browser/speech/speech_input_bubble.h"
8
9#import "base/memory/scoped_nsobject.h"
10#import "chrome/browser/ui/cocoa/speech_input_window_controller.h"
11#include "content/browser/tab_contents/tab_contents.h"
12#include "content/browser/tab_contents/tab_contents_view.h"
13#include "skia/ext/skia_utils_mac.h"
14
15namespace {
16
17// A class to bridge between the speech recognition C++ code and the Objective-C
18// bubble implementation. See chrome/browser/speech/speech_input_bubble.h for
19// more information on how this gets used.
20class SpeechInputBubbleImpl : public SpeechInputBubbleBase {
21 public:
22  SpeechInputBubbleImpl(TabContents* tab_contents,
23                        Delegate* delegate,
24                        const gfx::Rect& element_rect);
25  virtual ~SpeechInputBubbleImpl();
26  virtual void Show();
27  virtual void Hide();
28  virtual void UpdateLayout();
29  virtual void UpdateImage();
30
31 private:
32  scoped_nsobject<SpeechInputWindowController> window_;
33  Delegate* delegate_;
34  gfx::Rect element_rect_;
35};
36
37SpeechInputBubbleImpl::SpeechInputBubbleImpl(TabContents* tab_contents,
38                                             Delegate* delegate,
39                                             const gfx::Rect& element_rect)
40    : SpeechInputBubbleBase(tab_contents),
41      delegate_(delegate),
42      element_rect_(element_rect) {
43}
44
45SpeechInputBubbleImpl::~SpeechInputBubbleImpl() {
46  if (window_.get())
47    [window_.get() close];
48}
49
50void SpeechInputBubbleImpl::UpdateImage() {
51  if (window_.get())
52    [window_.get() setImage:gfx::SkBitmapToNSImage(icon_image())];
53}
54
55void SpeechInputBubbleImpl::Show() {
56  if (window_.get()) {
57    [window_.get() show];
58    return;
59  }
60
61  // Find the screen coordinates for the given tab and position the bubble's
62  // arrow anchor point inside that to point at the bottom-left of the html
63  // input element rect.
64  gfx::NativeView view = tab_contents()->view()->GetNativeView();
65  NSRect tab_bounds = [view bounds];
66  int anchor_x = tab_bounds.origin.x + element_rect_.x() +
67                 element_rect_.width() - kBubbleTargetOffsetX;
68  int anchor_y = tab_bounds.origin.y + tab_bounds.size.height -
69                 element_rect_.y() - element_rect_.height();
70  NSPoint anchor = NSMakePoint(anchor_x, anchor_y);
71  anchor = [view convertPoint:anchor toView:nil];
72  anchor = [[view window] convertBaseToScreen:anchor];
73
74  window_.reset([[SpeechInputWindowController alloc]
75      initWithParentWindow:tab_contents()->view()->GetTopLevelNativeWindow()
76                  delegate:delegate_
77                anchoredAt:anchor]);
78
79  UpdateLayout();
80  [window_.get() show];
81}
82
83void SpeechInputBubbleImpl::Hide() {
84  if (!window_.get())
85    return;
86
87  [window_.get() close];
88  window_.reset();
89}
90
91void SpeechInputBubbleImpl::UpdateLayout() {
92  if (!window_.get())
93    return;
94
95  [window_.get() updateLayout:display_mode()
96                  messageText:message_text()
97                    iconImage:gfx::SkBitmapToNSImage(icon_image())];
98}
99
100}  // namespace
101
102SpeechInputBubble* SpeechInputBubble::CreateNativeBubble(
103    TabContents* tab_contents,
104    Delegate* delegate,
105    const gfx::Rect& element_rect) {
106  return new SpeechInputBubbleImpl(tab_contents, delegate, element_rect);
107}
108
109