Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(8)

Side by Side Diff: ui/views/cocoa/bridged_content_view.mm

Issue 329463002: MacViews: Implement text input. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 6 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #import "ui/views/cocoa/bridged_content_view.h" 5 #import "ui/views/cocoa/bridged_content_view.h"
6 6
7 #include "base/strings/sys_string_conversions.h"
8 #include "grit/ui_strings.h"
9 #include "ui/base/ime/text_input_client.h"
7 #include "ui/gfx/mac/point_utils.h" 10 #include "ui/gfx/mac/point_utils.h"
8 #include "ui/accessibility/ax_view_state.h" 11 #include "ui/accessibility/ax_view_state.h"
9 #include "ui/gfx/canvas.h" 12 #include "ui/gfx/canvas.h"
10 #include "ui/gfx/canvas_paint_mac.h" 13 #include "ui/gfx/canvas_paint_mac.h"
14 #include "ui/gfx/geometry/rect.h"
15 #include "ui/gfx/mac/point_utils.h"
11 #include "ui/views/view.h" 16 #include "ui/views/view.h"
12 #include "ui/views/widget/widget.h" 17 #include "ui/views/widget/widget.h"
13 18
14 @interface BridgedContentView () 19 @interface BridgedContentView ()
15 20
16 // Passes the event to NativeWidgetMac for handling. 21 // Passes the event to NativeWidgetMac for handling.
17 - (void)handleUntranslatedKeyEvent:(NSEvent*)theEvent; 22 - (void)handleUntranslatedKeyEvent:(NSEvent*)theEvent;
18 23
19 // Translates the location of |theEvent| to toolkit-views coordinates and passes 24 // Translates the location of |theEvent| to toolkit-views coordinates and passes
20 // the event to NativeWidgetMac for handling. 25 // the event to NativeWidgetMac for handling.
(...skipping 13 matching lines...) Expand all
34 } 39 }
35 40
36 - (views::View*)view { 41 - (views::View*)view {
37 return hostedView_; 42 return hostedView_;
38 } 43 }
39 44
40 - (void)clearView { 45 - (void)clearView {
41 hostedView_ = NULL; 46 hostedView_ = NULL;
42 } 47 }
43 48
49 - (void)setTextInputClient:(ui::TextInputClient*)textInputClient {
50 textInputClient_ = textInputClient;
tapted 2014/06/17 13:23:56 Does toolkit-views guarantee to send OnDidChangeFo
Andre 2014/06/18 21:48:34 Yes, that should be handled through Widget::ViewHi
51 }
52
44 // BridgedContentView private implementation. 53 // BridgedContentView private implementation.
45 54
46 - (void)handleUntranslatedKeyEvent:(NSEvent*)theEvent { 55 - (void)handleUntranslatedKeyEvent:(NSEvent*)theEvent {
47 if (!hostedView_) 56 if (!hostedView_)
48 return; 57 return;
49 58
50 ui::KeyEvent event(theEvent, false); 59 ui::KeyEvent event(theEvent, false);
51 hostedView_->GetWidget()->OnKeyEvent(&event); 60 hostedView_->GetWidget()->OnKeyEvent(&event);
52 } 61 }
53 62
54 - (void)handleMouseEvent:(NSEvent*)theEvent { 63 - (void)handleMouseEvent:(NSEvent*)theEvent {
55 if (!hostedView_) 64 if (!hostedView_)
56 return; 65 return;
57 66
58 ui::MouseEvent event(theEvent); 67 ui::MouseEvent event(theEvent);
59 hostedView_->GetWidget()->OnMouseEvent(&event); 68 hostedView_->GetWidget()->OnMouseEvent(&event);
60 } 69 }
61 70
71 - (void)doCommandByID:(int)cmd_id {
tapted 2014/06/17 13:23:56 This should be declared in BridgedContentView () w
Andre 2014/06/18 21:48:34 Done.
72 if (textInputClient_ && textInputClient_->IsEditingCommandEnabled(cmd_id))
73 textInputClient_->ExecuteEditingCommand(cmd_id);
74 }
75
62 // NSView implementation. 76 // NSView implementation.
63 77
78 - (BOOL)acceptsFirstResponder {
79 return YES;
80 }
81
64 - (void)setFrame:(NSRect)newFrame { 82 - (void)setFrame:(NSRect)newFrame {
65 [super setFrame:newFrame]; 83 [super setFrame:newFrame];
66 if (!hostedView_) 84 if (!hostedView_)
67 return; 85 return;
68 86
69 hostedView_->SetSize(gfx::Size(NSWidth(newFrame), NSHeight(newFrame))); 87 hostedView_->SetSize(gfx::Size(NSWidth(newFrame), NSHeight(newFrame)));
70 } 88 }
71 89
72 - (void)drawRect:(NSRect)dirtyRect { 90 - (void)drawRect:(NSRect)dirtyRect {
73 if (!hostedView_) 91 if (!hostedView_)
74 return; 92 return;
75 93
76 gfx::CanvasSkiaPaint canvas(dirtyRect, false /* opaque */); 94 gfx::CanvasSkiaPaint canvas(dirtyRect, false /* opaque */);
77 hostedView_->Paint(&canvas, views::CullSet()); 95 hostedView_->Paint(&canvas, views::CullSet());
78 } 96 }
79 97
80 - (void)keyDown:(NSEvent*)theEvent { 98 - (void)keyDown:(NSEvent*)theEvent {
81 [self handleUntranslatedKeyEvent:theEvent]; 99 if (textInputClient_)
100 [self interpretKeyEvents:@[ theEvent ]];
tapted 2014/06/17 13:23:56 Do you think interpretKeyEvents will be needed for
Andre 2014/06/18 21:48:35 If textInputClient_ is NULL, I think we should for
tapted 2014/06/19 01:29:15 yep - lg for now. For things like menus/lists we'l
101 else
102 [self handleUntranslatedKeyEvent:theEvent];
82 } 103 }
83 104
84 - (void)keyUp:(NSEvent*)theEvent { 105 - (void)keyUp:(NSEvent*)theEvent {
85 [self handleUntranslatedKeyEvent:theEvent]; 106 [self handleUntranslatedKeyEvent:theEvent];
86 } 107 }
87 108
88 - (void)mouseDown:(NSEvent*)theEvent { 109 - (void)mouseDown:(NSEvent*)theEvent {
89 [self handleMouseEvent:theEvent]; 110 [self handleMouseEvent:theEvent];
90 } 111 }
91 112
92 - (void)mouseDragged:(NSEvent*)theEvent { 113 - (void)mouseDragged:(NSEvent*)theEvent {
93 [self handleMouseEvent:theEvent]; 114 [self handleMouseEvent:theEvent];
94 } 115 }
95 116
96 - (void)mouseUp:(NSEvent*)theEvent { 117 - (void)mouseUp:(NSEvent*)theEvent {
97 [self handleMouseEvent:theEvent]; 118 [self handleMouseEvent:theEvent];
98 } 119 }
99 120
121 - (void)deleteBackward:(id)sender {
122 [self doCommandByID:IDS_DELETE_BACKWARD];
123 }
124
125 - (void)deleteForward:(id)sender {
126 [self doCommandByID:IDS_DELETE_FORWARD];
127 }
128
129 - (void)moveLeft:(id)sender {
130 [self doCommandByID:IDS_MOVE_LEFT];
131 }
132
133 - (void)moveRight:(id)sender {
134 [self doCommandByID:IDS_MOVE_RIGHT];
135 }
136
137 // NSTextInputClient protocol implementation.
138
139 - (NSAttributedString*)attributedSubstringForProposedRange:(NSRange)range
tapted 2014/06/17 13:23:56 ugh longmethodnames. is this what clang-format doe
Andre 2014/06/18 21:48:34 Done.
140 actualRange:(NSRangePointer)actualRange {
141 base::string16 text;
tapted 2014/06/17 13:23:56 is there a better name for `text` - `substring` ma
Andre 2014/06/18 21:48:34 Done.
142 if (textInputClient_) {
143 gfx::Range textRange;
144 textInputClient_->GetTextRange(&textRange);
145 gfx::Range subrange = textRange.Intersect(gfx::Range(range));
146 textInputClient_->GetTextFromRange(subrange, &text);
147 if (actualRange)
148 *actualRange = subrange.ToNSRange();
149 }
150 return [[[NSAttributedString alloc]
151 initWithString:base::SysUTF16ToNSString(text)] autorelease];
152 }
153
154 - (NSUInteger)characterIndexForPoint:(NSPoint)aPoint {
155 NOTIMPLEMENTED();
156 return 0;
157 }
158
159 - (void)doCommandBySelector:(SEL)selector {
tapted 2014/06/17 13:23:56 Should be under `// NSResponder implementation.`.
Andre 2014/06/18 21:48:34 doCommandBySelector is part of both NSResponder an
tapted 2014/06/19 01:29:15 It's still overriding a method on NSResponder (whe
160 if ([self respondsToSelector:selector])
161 [self performSelector:selector withObject:nil];
162 }
163
164 - (NSRect)firstRectForCharacterRange:(NSRange)range
165 actualRange:(NSRangePointer)actualRange {
166 // FIXME(andresantoso): ui::TextInputClient does not expose this.
tapted 2014/06/17 13:23:56 I don't typically see FIXME comments. TODO is usua
Andre 2014/06/18 21:48:34 Yep, that was a temporary experiment. I've changed
167 return textInputClient_
168 ? gfx::ScreenRectToNSRect(textInputClient_->GetCaretBounds())
169 : NSZeroRect;
170 }
171
172 - (BOOL)hasMarkedText {
173 return textInputClient_ && textInputClient_->HasCompositionText();
174 }
175
176 - (void)insertText:(id)text replacementRange:(NSRange)replacementRange {
tapted 2014/06/17 13:23:56 nit: I think method signatures "always" linebreak
Andre 2014/06/18 21:48:34 Hmm, I don't see that in objcstyle, and cocoa code
tapted 2014/06/19 01:29:15 Oh wow - I've just always done it - but you're rig
177 if ([text isKindOfClass:[NSAttributedString class]])
tapted 2014/06/17 13:23:56 Before this, you should do if (!textInputClient_)
Andre 2014/06/18 21:48:34 Done.
tapted 2014/06/19 01:29:15 `if (!textInputClient_)` should be the first line
Andre 2014/06/19 23:20:25 Done.
178 text = [text string];
179 if (textInputClient_) {
180 textInputClient_->DeleteRange(gfx::Range(replacementRange));
181 textInputClient_->InsertText(base::SysNSStringToUTF16(text));
182 }
183 }
184
185 - (NSRange)markedRange {
186 gfx::Range range;
tapted 2014/06/17 13:23:56 if (!textInputClient_) return NSMakeRange(0, 0);
Andre 2014/06/18 21:48:34 Done.
187 if (textInputClient_)
188 textInputClient_->GetCompositionTextRange(&range);
189 return range.ToNSRange();
190 }
191
192 - (NSRange)selectedRange {
193 gfx::Range range;
194 if (textInputClient_)
195 textInputClient_->GetSelectionRange(&range);
196 return range.ToNSRange();
197 }
198
199 - (void)setMarkedText:(id)text
200 selectedRange:(NSRange)selectedRange
201 replacementRange:(NSRange)replacementRange {
202 if ([text isKindOfClass:[NSAttributedString class]])
203 text = [text string];
204
205 if (textInputClient_) {
206 ui::CompositionText composition;
207 composition.text = base::SysNSStringToUTF16(text);
208 composition.selection = gfx::Range(selectedRange);
209 textInputClient_->SetCompositionText(composition);
210 }
211 }
212
213 - (void)unmarkText {
214 if (textInputClient_)
215 textInputClient_->ConfirmCompositionText();
216 }
217
218 - (NSArray*)validAttributesForMarkedText {
219 return @[];
220 }
221
100 @end 222 @end
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698