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
3 // found in the LICENSE file.
5 #import "ui/views/cocoa/bridged_content_view.h"
7 #include "base/logging.h"
8 #include "base/strings/sys_string_conversions.h"
9 #include "grit/ui_strings.h"
10 #include "ui/base/ime/text_input_client.h"
11 #include "ui/gfx/canvas_paint_mac.h"
12 #include "ui/gfx/geometry/rect.h"
13 #include "ui/views/view.h"
15 @interface BridgedContentView ()
17 // Execute a command on the currently focused TextInputClient.
18 // |commandId| should be a resource ID from ui_strings.grd.
19 - (void)doCommandByID:(int)commandId;
23 @implementation BridgedContentView
25 @synthesize hostedView = hostedView_;
26 @synthesize textInputClient = textInputClient_;
28 - (id)initWithView:(views::View*)viewToHost {
30 gfx::Rect bounds = viewToHost->bounds();
31 // To keep things simple, assume the origin is (0, 0) until there exists a use
32 // case for something other than that.
33 DCHECK(bounds.origin().IsOrigin());
34 NSRect initialFrame = NSMakeRect(0, 0, bounds.width(), bounds.height());
35 if ((self = [super initWithFrame:initialFrame]))
36 hostedView_ = viewToHost;
45 // BridgedContentView private implementation.
47 - (void)doCommandByID:(int)commandId {
48 if (textInputClient_ && textInputClient_->IsEditingCommandEnabled(commandId))
49 textInputClient_->ExecuteEditingCommand(commandId);
52 // NSView implementation.
54 - (void)setFrameSize:(NSSize)newSize {
55 [super setFrameSize:newSize];
59 hostedView_->SetSize(gfx::Size(newSize.width, newSize.height));
62 - (void)drawRect:(NSRect)dirtyRect {
66 gfx::CanvasSkiaPaint canvas(dirtyRect, false /* opaque */);
67 hostedView_->Paint(&canvas, views::CullSet());
70 - (void)keyDown:(NSEvent*)theEvent {
72 [self interpretKeyEvents:@[ theEvent ]];
74 [super keyDown:theEvent];
77 - (void)deleteBackward:(id)sender {
78 [self doCommandByID:IDS_DELETE_BACKWARD];
81 - (void)deleteForward:(id)sender {
82 [self doCommandByID:IDS_DELETE_FORWARD];
85 - (void)moveLeft:(id)sender {
86 [self doCommandByID:IDS_MOVE_LEFT];
89 - (void)moveRight:(id)sender {
90 [self doCommandByID:IDS_MOVE_RIGHT];
93 // NSTextInputClient protocol implementation.
95 - (NSAttributedString*)
96 attributedSubstringForProposedRange:(NSRange)range
97 actualRange:(NSRangePointer)actualRange {
98 base::string16 substring;
99 if (textInputClient_) {
100 gfx::Range textRange;
101 textInputClient_->GetTextRange(&textRange);
102 gfx::Range subrange = textRange.Intersect(gfx::Range(range));
103 textInputClient_->GetTextFromRange(subrange, &substring);
105 *actualRange = subrange.ToNSRange();
107 return [[[NSAttributedString alloc]
108 initWithString:base::SysUTF16ToNSString(substring)] autorelease];
111 - (NSUInteger)characterIndexForPoint:(NSPoint)aPoint {
116 - (void)doCommandBySelector:(SEL)selector {
117 if ([self respondsToSelector:selector])
118 [self performSelector:selector withObject:nil];
120 [[self nextResponder] doCommandBySelector:selector];
123 - (NSRect)firstRectForCharacterRange:(NSRange)range
124 actualRange:(NSRangePointer)actualRange {
129 - (BOOL)hasMarkedText {
130 return textInputClient_ && textInputClient_->HasCompositionText();
133 - (void)insertText:(id)text replacementRange:(NSRange)replacementRange {
134 if (!textInputClient_)
137 if ([text isKindOfClass:[NSAttributedString class]])
138 text = [text string];
139 textInputClient_->DeleteRange(gfx::Range(replacementRange));
140 textInputClient_->InsertText(base::SysNSStringToUTF16(text));
143 - (NSRange)markedRange {
144 if (!textInputClient_)
145 return NSMakeRange(NSNotFound, 0);
148 textInputClient_->GetCompositionTextRange(&range);
149 return range.ToNSRange();
152 - (NSRange)selectedRange {
153 if (!textInputClient_)
154 return NSMakeRange(NSNotFound, 0);
157 textInputClient_->GetSelectionRange(&range);
158 return range.ToNSRange();
161 - (void)setMarkedText:(id)text
162 selectedRange:(NSRange)selectedRange
163 replacementRange:(NSRange)replacementRange {
164 if (!textInputClient_)
167 if ([text isKindOfClass:[NSAttributedString class]])
168 text = [text string];
169 ui::CompositionText composition;
170 composition.text = base::SysNSStringToUTF16(text);
171 composition.selection = gfx::Range(selectedRange);
172 textInputClient_->SetCompositionText(composition);
176 if (textInputClient_)
177 textInputClient_->ConfirmCompositionText();
180 - (NSArray*)validAttributesForMarkedText {