Home | History | Annotate | Download | only in speech
      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 
     15 namespace {
     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.
     20 class 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 
     37 SpeechInputBubbleImpl::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 
     45 SpeechInputBubbleImpl::~SpeechInputBubbleImpl() {
     46   if (window_.get())
     47     [window_.get() close];
     48 }
     49 
     50 void SpeechInputBubbleImpl::UpdateImage() {
     51   if (window_.get())
     52     [window_.get() setImage:gfx::SkBitmapToNSImage(icon_image())];
     53 }
     54 
     55 void 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 
     83 void SpeechInputBubbleImpl::Hide() {
     84   if (!window_.get())
     85     return;
     86 
     87   [window_.get() close];
     88   window_.reset();
     89 }
     90 
     91 void 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 
    102 SpeechInputBubble* 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