c308f5a931fbdf6368b38634459856259b5ba4ba
[platform/framework/web/crosswalk.git] / src / chrome / browser / ui / cocoa / speech_recognition_bubble_cocoa.mm
1 // Copyright (c) 2012 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_recognition_bubble.h"
8
9 #import "base/mac/scoped_nsobject.h"
10 #include "chrome/browser/ui/browser.h"
11 #include "chrome/browser/ui/cocoa/browser_window_cocoa.h"
12 #include "chrome/browser/ui/cocoa/browser_window_controller.h"
13 #include "chrome/browser/ui/cocoa/location_bar/location_bar_view_mac.h"
14 #import "chrome/browser/ui/cocoa/speech_recognition_window_controller.h"
15 #include "content/public/browser/web_contents.h"
16 #include "content/public/browser/web_contents_view.h"
17 #include "ui/gfx/image/image_skia_util_mac.h"
18
19 using content::WebContents;
20
21 namespace {
22
23 // A class to bridge between the speech recognition C++ code and the Objective-C
24 // bubble implementation. See chrome/browser/speech/speech_recognition_bubble.h
25 // for more information on how this gets used.
26 class SpeechRecognitionBubbleImpl : public SpeechRecognitionBubbleBase {
27  public:
28   SpeechRecognitionBubbleImpl(WebContents* web_contents,
29                               Delegate* delegate,
30                               const gfx::Rect& element_rect);
31   virtual ~SpeechRecognitionBubbleImpl();
32   virtual void Show() OVERRIDE;
33   virtual void Hide() OVERRIDE;
34   virtual void UpdateLayout() OVERRIDE;
35   virtual void UpdateImage() OVERRIDE;
36
37  private:
38   base::scoped_nsobject<SpeechRecognitionWindowController> window_;
39   Delegate* delegate_;
40   gfx::Rect element_rect_;
41 };
42
43 SpeechRecognitionBubbleImpl::SpeechRecognitionBubbleImpl(
44     WebContents* web_contents,
45     Delegate* delegate,
46     const gfx::Rect& element_rect)
47     : SpeechRecognitionBubbleBase(web_contents),
48       delegate_(delegate),
49       element_rect_(element_rect) {
50 }
51
52 SpeechRecognitionBubbleImpl::~SpeechRecognitionBubbleImpl() {
53   if (window_.get())
54     [window_.get() close];
55 }
56
57 void SpeechRecognitionBubbleImpl::UpdateImage() {
58   if (window_.get())
59     [window_.get() setImage:gfx::NSImageFromImageSkia(icon_image())];
60 }
61
62 void SpeechRecognitionBubbleImpl::Show() {
63   if (window_.get()) {
64     [window_.get() show];
65     return;
66   }
67
68   // Find the screen coordinates for the given tab and position the bubble's
69   // arrow anchor point inside that to point at the bottom-left of the html
70   // input element rect if the position is valid, otherwise point it towards
71   // the page icon in the omnibox.
72   gfx::NativeView view = GetWebContents()->GetView()->GetNativeView();
73   NSWindow* parent_window = [view window];
74   NSRect tab_bounds = [view bounds];
75   int anchor_x = tab_bounds.origin.x + element_rect_.x() +
76                  element_rect_.width() - kBubbleTargetOffsetX;
77   int anchor_y = tab_bounds.origin.y + tab_bounds.size.height -
78                  element_rect_.y() - element_rect_.height();
79
80   NSPoint anchor = NSMakePoint(anchor_x, anchor_y);
81   if (NSPointInRect(anchor, tab_bounds)) {
82     // Good, convert to window coordinates.
83     anchor = [view convertPoint:anchor toView:nil];
84   } else {
85     LocationBarViewMac* locationBar =
86         [[parent_window windowController] locationBarBridge];
87
88     if (locationBar) {
89       anchor = locationBar->GetPageInfoBubblePoint();
90     } else {
91       // This is very rare, but possible. Just use the top-left corner.
92       // See http://crbug.com/119237
93       anchor = NSMakePoint(NSMinX(tab_bounds), NSMaxY(tab_bounds));
94       anchor = [view convertPoint:anchor toView:nil];
95     }
96   }
97
98   anchor = [parent_window convertBaseToScreen:anchor];
99
100   window_.reset([[SpeechRecognitionWindowController alloc]
101       initWithParentWindow:parent_window
102                   delegate:delegate_
103                 anchoredAt:anchor]);
104
105   UpdateLayout();
106   [window_.get() show];
107 }
108
109 void SpeechRecognitionBubbleImpl::Hide() {
110   if (!window_.get())
111     return;
112
113   [window_.get() close];
114   window_.reset();
115 }
116
117 void SpeechRecognitionBubbleImpl::UpdateLayout() {
118   if (!window_.get())
119     return;
120
121   [window_.get() updateLayout:display_mode()
122                   messageText:message_text()
123                     iconImage:gfx::NSImageFromImageSkia(icon_image())];
124 }
125
126 }  // namespace
127
128 SpeechRecognitionBubble* SpeechRecognitionBubble::CreateNativeBubble(
129     WebContents* web_contents,
130     Delegate* delegate,
131     const gfx::Rect& element_rect) {
132   return new SpeechRecognitionBubbleImpl(web_contents, delegate, element_rect);
133 }