OLD | NEW |
| (Empty) |
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_input_bubble.h" | |
8 | |
9 #import "base/memory/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_input_window_controller.h" | |
15 #include "content/public/browser/web_contents.h" | |
16 #include "content/public/browser/web_contents_view.h" | |
17 #include "skia/ext/skia_utils_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_input_bubble.h for | |
25 // more information on how this gets used. | |
26 class SpeechInputBubbleImpl : public SpeechInputBubbleBase { | |
27 public: | |
28 SpeechInputBubbleImpl(WebContents* web_contents, | |
29 Delegate* delegate, | |
30 const gfx::Rect& element_rect); | |
31 virtual ~SpeechInputBubbleImpl(); | |
32 virtual void Show(); | |
33 virtual void Hide(); | |
34 virtual void UpdateLayout(); | |
35 virtual void UpdateImage(); | |
36 | |
37 private: | |
38 scoped_nsobject<SpeechInputWindowController> window_; | |
39 Delegate* delegate_; | |
40 gfx::Rect element_rect_; | |
41 }; | |
42 | |
43 SpeechInputBubbleImpl::SpeechInputBubbleImpl(WebContents* web_contents, | |
44 Delegate* delegate, | |
45 const gfx::Rect& element_rect) | |
46 : SpeechInputBubbleBase(web_contents), | |
47 delegate_(delegate), | |
48 element_rect_(element_rect) { | |
49 } | |
50 | |
51 SpeechInputBubbleImpl::~SpeechInputBubbleImpl() { | |
52 if (window_.get()) | |
53 [window_.get() close]; | |
54 } | |
55 | |
56 void SpeechInputBubbleImpl::UpdateImage() { | |
57 if (window_.get()) | |
58 [window_.get() setImage:gfx::SkBitmapToNSImage(icon_image())]; | |
59 } | |
60 | |
61 void SpeechInputBubbleImpl::Show() { | |
62 if (window_.get()) { | |
63 [window_.get() show]; | |
64 return; | |
65 } | |
66 | |
67 // Find the screen coordinates for the given tab and position the bubble's | |
68 // arrow anchor point inside that to point at the bottom-left of the html | |
69 // input element rect if the position is valid, otherwise point it towards | |
70 // the page icon in the omnibox. | |
71 gfx::NativeView view = web_contents()->GetView()->GetNativeView(); | |
72 NSWindow* parentWindow = web_contents()->GetView()->GetTopLevelNativeWindow(); | |
73 NSRect tab_bounds = [view bounds]; | |
74 int anchor_x = tab_bounds.origin.x + element_rect_.x() + | |
75 element_rect_.width() - kBubbleTargetOffsetX; | |
76 int anchor_y = tab_bounds.origin.y + tab_bounds.size.height - | |
77 element_rect_.y() - element_rect_.height(); | |
78 NSPoint anchor = NSZeroPoint; | |
79 if (anchor_x < 0 || anchor_y < 0 || | |
80 anchor_x > NSWidth([parentWindow frame]) || | |
81 anchor_y > NSHeight([parentWindow frame])) { | |
82 LocationBarViewMac* locationBar = | |
83 [[parentWindow windowController] locationBarBridge]; | |
84 anchor = locationBar->GetPageInfoBubblePoint(); | |
85 } else { | |
86 anchor = NSMakePoint(anchor_x, anchor_y); | |
87 } | |
88 anchor = [view convertPoint:anchor toView:nil]; | |
89 anchor = [[view window] convertBaseToScreen:anchor]; | |
90 | |
91 window_.reset([[SpeechInputWindowController alloc] | |
92 initWithParentWindow:parentWindow | |
93 delegate:delegate_ | |
94 anchoredAt:anchor]); | |
95 | |
96 UpdateLayout(); | |
97 [window_.get() show]; | |
98 } | |
99 | |
100 void SpeechInputBubbleImpl::Hide() { | |
101 if (!window_.get()) | |
102 return; | |
103 | |
104 [window_.get() close]; | |
105 window_.reset(); | |
106 } | |
107 | |
108 void SpeechInputBubbleImpl::UpdateLayout() { | |
109 if (!window_.get()) | |
110 return; | |
111 | |
112 [window_.get() updateLayout:display_mode() | |
113 messageText:message_text() | |
114 iconImage:gfx::SkBitmapToNSImage(icon_image())]; | |
115 } | |
116 | |
117 } // namespace | |
118 | |
119 SpeechInputBubble* SpeechInputBubble::CreateNativeBubble( | |
120 WebContents* web_contents, | |
121 Delegate* delegate, | |
122 const gfx::Rect& element_rect) { | |
123 return new SpeechInputBubbleImpl(web_contents, delegate, element_rect); | |
124 } | |
125 | |
OLD | NEW |