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

Unified 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: Fixes for tapted 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 side-by-side diff with in-line comments
Download patch
Index: ui/views/cocoa/bridged_content_view.mm
diff --git a/ui/views/cocoa/bridged_content_view.mm b/ui/views/cocoa/bridged_content_view.mm
index fda514016bf89e228e0b7ea3c044b6b6e1a5d5d3..4af2aeaf14d1ba24343c537af5ac49f9f6c683f7 100644
--- a/ui/views/cocoa/bridged_content_view.mm
+++ b/ui/views/cocoa/bridged_content_view.mm
@@ -5,7 +5,14 @@
#import "ui/views/cocoa/bridged_content_view.h"
#include "base/logging.h"
+#include "base/strings/sys_string_conversions.h"
+#include "grit/ui_strings.h"
+#include "ui/accessibility/ax_view_state.h"
+#include "ui/base/ime/text_input_client.h"
+#include "ui/gfx/canvas.h"
#include "ui/gfx/canvas_paint_mac.h"
+#include "ui/gfx/geometry/rect.h"
+#import "ui/views/cocoa/bridged_native_widget.h"
#include "ui/views/view.h"
#include "ui/views/widget/widget.h"
@@ -15,27 +22,40 @@
// the event to NativeWidgetMac for handling.
- (void)handleMouseEvent:(NSEvent*)theEvent;
+// Execute a command on the currently focused TextInputClient.
tapted 2014/06/19 01:29:16 nit: mention that |commandId| should be a resource
Andre 2014/06/19 23:20:26 Done.
+- (void)doCommandByID:(int)commandId;
+
@end
@implementation BridgedContentView
@synthesize hostedView = hostedView_;
+@synthesize textInputClient = textInputClient_;
-- (id)initWithView:(views::View*)viewToHost {
+- (id)initWithView:(views::View*)viewToHost
+ parent:(views::BridgedNativeWidget*)parent {
DCHECK(viewToHost);
+ DCHECK(parent);
gfx::Rect bounds = viewToHost->bounds();
// To keep things simple, assume the origin is (0, 0) until there exists a use
// case for something other than that.
DCHECK(bounds.origin().IsOrigin());
NSRect initialFrame = NSMakeRect(0, 0, bounds.width(), bounds.height());
- if ((self = [super initWithFrame:initialFrame]))
+ if ((self = [super initWithFrame:initialFrame])) {
hostedView_ = viewToHost;
-
+ parent_ = parent;
+ if (hostedView_->GetFocusManager())
+ hostedView_->GetFocusManager()->AddFocusChangeListener(parent_);
tapted 2014/06/19 01:29:15 Hm - I just looked at this some more. Does this al
Andre 2014/06/19 23:20:26 I like it, moved this to BridgedNativeWidget.
+ }
return self;
}
- (void)clearView {
- hostedView_ = NULL;
+ if (hostedView_) {
tapted 2014/06/19 01:29:16 if (!hostedView_) return; or perhaps even DCHE
Andre 2014/06/19 23:20:26 Removed this change from the patch.
+ if (hostedView_->GetFocusManager())
tapted 2014/06/19 01:29:16 note that we'll have to ensure the lifetime of thi
+ hostedView_->GetFocusManager()->RemoveFocusChangeListener(parent_);
+ hostedView_ = NULL;
+ }
}
// BridgedContentView private implementation.
@@ -48,8 +68,17 @@
hostedView_->GetWidget()->OnMouseEvent(&event);
}
+- (void)doCommandByID:(int)commandId {
+ if (textInputClient_ && textInputClient_->IsEditingCommandEnabled(commandId))
+ textInputClient_->ExecuteEditingCommand(commandId);
+}
+
// NSView implementation.
+- (BOOL)acceptsFirstResponder {
+ return YES;
+}
+
- (void)setFrameSize:(NSSize)newSize {
[super setFrameSize:newSize];
if (!hostedView_)
@@ -118,4 +147,116 @@
[self handleMouseEvent:theEvent];
}
+- (void)keyDown:(NSEvent*)theEvent {
+ if (textInputClient_)
+ [self interpretKeyEvents:@[ theEvent ]];
+ else
+ [super keyDown:theEvent];
+}
+
+- (void)deleteBackward:(id)sender {
+ [self doCommandByID:IDS_DELETE_BACKWARD];
+}
+
+- (void)deleteForward:(id)sender {
+ [self doCommandByID:IDS_DELETE_FORWARD];
+}
+
+- (void)moveLeft:(id)sender {
+ [self doCommandByID:IDS_MOVE_LEFT];
+}
+
+- (void)moveRight:(id)sender {
+ [self doCommandByID:IDS_MOVE_RIGHT];
+}
+
+// NSTextInputClient protocol implementation.
+
+- (NSAttributedString*)
+ attributedSubstringForProposedRange:(NSRange)range
+ actualRange:(NSRangePointer)actualRange {
+ base::string16 substring;
+ if (textInputClient_) {
+ gfx::Range textRange;
+ textInputClient_->GetTextRange(&textRange);
+ gfx::Range subrange = textRange.Intersect(gfx::Range(range));
+ textInputClient_->GetTextFromRange(subrange, &substring);
+ if (actualRange)
+ *actualRange = subrange.ToNSRange();
+ }
+ return [[[NSAttributedString alloc]
+ initWithString:base::SysUTF16ToNSString(substring)] autorelease];
+}
+
+- (NSUInteger)characterIndexForPoint:(NSPoint)aPoint {
+ NOTIMPLEMENTED();
+ return 0;
+}
+
+- (void)doCommandBySelector:(SEL)selector {
+ if ([self respondsToSelector:selector])
+ [self performSelector:selector withObject:nil];
+ else
+ [[self nextResponder] doCommandBySelector:selector];
+}
+
+- (NSRect)firstRectForCharacterRange:(NSRange)range
+ actualRange:(NSRangePointer)actualRange {
+ NOTIMPLEMENTED();
+ return NSZeroRect;
+}
+
+- (BOOL)hasMarkedText {
+ return textInputClient_ && textInputClient_->HasCompositionText();
+}
+
+- (void)insertText:(id)text replacementRange:(NSRange)replacementRange {
+ if (textInputClient_) {
+ if ([text isKindOfClass:[NSAttributedString class]])
+ text = [text string];
+ textInputClient_->DeleteRange(gfx::Range(replacementRange));
+ textInputClient_->InsertText(base::SysNSStringToUTF16(text));
+ }
+}
+
+- (NSRange)markedRange {
+ if (!textInputClient_)
+ return NSMakeRange(0, 0);
tapted 2014/06/19 01:29:16 oops - my bad. this should be NSMakeRange(NSNotFou
Andre 2014/06/19 23:20:26 Done.
+
+ gfx::Range range;
+ textInputClient_->GetCompositionTextRange(&range);
+ return range.ToNSRange();
+}
+
+- (NSRange)selectedRange {
+ if (!textInputClient_)
+ return NSMakeRange(0, 0);
+
+ gfx::Range range;
+ textInputClient_->GetSelectionRange(&range);
+ return range.ToNSRange();
+}
+
+- (void)setMarkedText:(id)text
+ selectedRange:(NSRange)selectedRange
+ replacementRange:(NSRange)replacementRange {
+ if (textInputClient_) {
tapted 2014/06/19 01:29:16 same here - prefer early return / less indenting
Andre 2014/06/19 23:20:26 Done.
+ if ([text isKindOfClass:[NSAttributedString class]])
+ text = [text string];
+ ui::CompositionText composition;
+ composition.text = base::SysNSStringToUTF16(text);
+ composition.selection = gfx::Range(selectedRange);
+ textInputClient_->SetCompositionText(composition);
+ }
+}
+
+- (void)unmarkText {
+ if (textInputClient_)
+ textInputClient_->ConfirmCompositionText();
+}
+
+- (NSArray*)validAttributesForMarkedText {
+ return @[];
+}
+
@end

Powered by Google App Engine
This is Rietveld 408576698