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 |
new file mode 100644 |
index 0000000000000000000000000000000000000000..7667924a353f91517ec2caae2c1cec41582a627e |
--- /dev/null |
+++ b/ui/views/cocoa/bridged_content_view.mm |
@@ -0,0 +1,153 @@ |
+// Copyright 2014 The Chromium Authors. All rights reserved. |
+// Use of this source code is governed by a BSD-style license that can be |
+// found in the LICENSE file. |
+ |
+#import "ui/views/cocoa/bridged_content_view.h" |
+ |
+#include "ui/gfx/mac/point_utils.h" |
+#include "ui/accessibility/ax_view_state.h" |
+#include "ui/gfx/canvas.h" |
+#include "ui/gfx/canvas_paint_mac.h" |
+#include "ui/views/view.h" |
+#include "ui/views/widget/widget.h" |
+ |
+namespace { |
+ |
+template <class OSTREAM> |
+OSTREAM& operator<<(OSTREAM& out, const NSRect& rect) { |
+ CGFloat x = rect.origin.x; |
+ CGFloat y = rect.origin.y; |
+ out << '[' << rect.size.width << 'x' << rect.size.height |
+ << (x < 0 ? '-' : '+') << x << (y < 0 ? '-' : '+') << y << ']'; |
+ return out; |
+} |
+ |
+template <class OSTREAM> |
+OSTREAM& operator<<(OSTREAM& out, const NSPoint& point) { |
+ out << '(' << point.x << ',' << point.y << ')'; |
+ return out; |
+} |
+} |
+ |
+@implementation BridgedContentView |
+ |
+- (id)initWithView:(views::View*)viewToHost { |
+ DCHECK(viewToHost); |
+ NSRect initialFrame = ScreenRectToNSRect(viewToHost->bounds()); |
+ if ((self = [super initWithFrame:initialFrame])) { |
+ hostedView_ = viewToHost; |
+ } |
+ return self; |
+} |
+ |
+- (views::View*)view { |
+ return hostedView_; |
+} |
+ |
+- (void)clearView { |
+ hostedView_ = NULL; |
+} |
+ |
+// BridgedContentView private implementation. |
+ |
+- (void)handleMouseEvent:(NSEvent*)theEvent { |
+ if (!hostedView_) |
+ return; |
+ |
+ ui::MouseEvent event(theEvent); |
+ |
+ NSPoint windowLocation = [theEvent locationInWindow]; |
+ NSPoint viewLocation = [self convertPoint:windowLocation fromView:nil]; |
+ event.set_location(event.location() + |
+ gfx::Vector2dF(viewLocation.x - windowLocation.x, |
+ viewLocation.y - windowLocation.y)); |
+ |
+ { |
+ gfx::Point uiViewLocation = event.location(); |
+ views::View::ConvertPointFromWidget(hostedView_, &uiViewLocation); |
+ |
+ DLOG(INFO) << "Forwarding mouse event in " << [self frame] << " " |
+ << hostedView_->GetClassName() << ":" |
+ << " window" << windowLocation << " view" << viewLocation |
+ << " ui.Location: " << event.location_f().ToString() |
+ << " ui.ViewLocation: " << uiViewLocation.ToString(); |
+ } |
+ |
+ hostedView_->GetWidget()->OnMouseEvent(&event); |
+} |
+ |
+// NSView implementation. |
+ |
+- (void)setFrame:(NSRect)newFrame { |
+ [super setFrame:newFrame]; |
+ hostedView_->SetSize(gfx::Size(NSWidth(newFrame), NSHeight(newFrame))); |
+} |
+ |
+- (void)drawRect:(NSRect)dirtyRect { |
+ if (!hostedView_) |
+ return; |
+ |
+ gfx::CanvasSkiaPaint canvas(dirtyRect, false /* opaque */); |
+ hostedView_->Paint(&canvas, views::CullSet()); |
+} |
+ |
+- (void)mouseDown:(NSEvent*)theEvent { |
+ [self handleMouseEvent:theEvent]; |
+} |
+ |
+- (void)mouseDragged:(NSEvent*)theEvent { |
+ [self handleMouseEvent:theEvent]; |
+} |
+ |
+- (void)mouseUp:(NSEvent*)theEvent { |
+ [self handleMouseEvent:theEvent]; |
+} |
+ |
+// NSAccessibility informal protocol implementation. |
+ |
+- (NSArray*)accessibilityAttributeNames { |
+ NSMutableArray* attributes = |
+ [[super accessibilityAttributeNames] mutableCopy]; |
+ if (!hostedView_) |
+ return [attributes autorelease]; |
+ |
+ [attributes addObject:NSAccessibilityValueAttribute]; |
+ [attributes addObject:NSAccessibilityDescriptionAttribute]; |
+ return [attributes autorelease]; |
+} |
+ |
+- (id)accessibilityAttributeValue:(NSString*)attribute { |
+ if (!hostedView_) |
+ return [super accessibilityAttributeValue:attribute]; |
+ |
+ ui::AXViewState state; |
+ hostedView_->GetAccessibleState(&state); |
+ switch (state.role) { |
+ default: |
+ NOTREACHED(); |
+ } |
+#if 0 |
+ if ([attribute isEqual:NSAccessibilityRoleAttribute]) |
+ return NSAccessibilityTabGroupRole; |
+ if ([attribute isEqual:NSAccessibilityTabsAttribute]) { |
+ NSMutableArray* tabs = [[[NSMutableArray alloc] init] autorelease]; |
+ NSArray* children = |
+ [self accessibilityAttributeValue:NSAccessibilityChildrenAttribute]; |
+ for (id child in children) { |
+ if ([[child accessibilityAttributeValue:NSAccessibilityRoleAttribute] |
+ isEqual:NSAccessibilityRadioButtonRole]) { |
+ [tabs addObject:child]; |
+ } |
+ } |
+ return tabs; |
+ } |
+ if ([attribute isEqual:NSAccessibilityContentsAttribute]) |
+ return [self accessibilityAttributeValue:NSAccessibilityChildrenAttribute]; |
+ if ([attribute isEqual:NSAccessibilityValueAttribute]) |
+ return [controller_ activeTabView]; |
+#endif |
+ |
+ return [super accessibilityAttributeValue:attribute]; |
+} |
+ |
+@end |