Commit 8d3f418a authored by groby@chromium.org's avatar groby@chromium.org

[rAC] Allow clickthrough for SuggestionView

Most of the contents in AutofillSuggestionContainer should ignore mouse
clicks and instead let the SectionContainer handle it - the only
exception being the |inputField_| in the SuggestionContainer. This will
allow the suggestion menu to pop up even when the user clicks e.g. on
explanatory text.

Modified hitTest: to ignore all subviews except |inputField_| and
descendants.

BUG=331130
R=rsesek@chromium.org

Review URL: https://codereview.chromium.org/124383010

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@243673 0039d316-1c4b-4281-b951-d872f2087c98
parent dcd57350
...@@ -54,6 +54,34 @@ const CGFloat kLabelWithInputTopPadding = 5.0; ...@@ -54,6 +54,34 @@ const CGFloat kLabelWithInputTopPadding = 5.0;
@end @end
@interface AutofillSuggestionView : NSView {
@private
// The main input field - only view not ignoring mouse events.
NSView* inputField_;
}
@property (assign, nonatomic) NSView* inputField;
@end
// The suggestion container should ignore any mouse events unless they occur
// within the bounds of an editable field.
@implementation AutofillSuggestionView
@synthesize inputField = inputField_;
- (NSView*)hitTest:(NSPoint)point {
NSView* hitView = [super hitTest:point];
if ([hitView isDescendantOf:inputField_])
return hitView;
return nil;
}
@end
@implementation IconAttachmentCell @implementation IconAttachmentCell
- (NSPoint)cellBaselineOffset { - (NSPoint)cellBaselineOffset {
...@@ -130,9 +158,11 @@ const CGFloat kLabelWithInputTopPadding = 5.0; ...@@ -130,9 +158,11 @@ const CGFloat kLabelWithInputTopPadding = 5.0;
[spacer_ setBoxType:NSBoxSeparator]; [spacer_ setBoxType:NSBoxSeparator];
[spacer_ setBorderType:NSLineBorder]; [spacer_ setBorderType:NSLineBorder];
base::scoped_nsobject<NSView> view([[NSView alloc] initWithFrame:NSZeroRect]); base::scoped_nsobject<AutofillSuggestionView> view(
[[AutofillSuggestionView alloc] initWithFrame:NSZeroRect]);
[view setSubviews: [view setSubviews:
@[ label_, inputField_, spacer_ ]]; @[ label_, inputField_, spacer_ ]];
[view setInputField:inputField_];
[self setView:view]; [self setView:view];
} }
......
...@@ -16,10 +16,12 @@ class AutofillSuggestionContainerTest : public ui::CocoaTest { ...@@ -16,10 +16,12 @@ class AutofillSuggestionContainerTest : public ui::CocoaTest {
CocoaTest::SetUp(); CocoaTest::SetUp();
container_.reset([[AutofillSuggestionContainer alloc] init]); container_.reset([[AutofillSuggestionContainer alloc] init]);
[[test_window() contentView] addSubview:[container_ view]]; [[test_window() contentView] addSubview:[container_ view]];
view_ = [container_ view];
} }
protected: protected:
base::scoped_nsobject<AutofillSuggestionContainer> container_; base::scoped_nsobject<AutofillSuggestionContainer> container_;
NSView* view_;
}; };
} // namespace } // namespace
...@@ -44,3 +46,52 @@ TEST_F(AutofillSuggestionContainerTest, HasSubviews) { ...@@ -44,3 +46,52 @@ TEST_F(AutofillSuggestionContainerTest, HasSubviews) {
EXPECT_TRUE(has_text_view); EXPECT_TRUE(has_text_view);
EXPECT_TRUE(has_edit_field); EXPECT_TRUE(has_edit_field);
} }
// Test that mouse events outside the input field are ignored.
TEST_F(AutofillSuggestionContainerTest, HitTestInputField) {
base::scoped_nsobject<NSImage> icon(
[[NSImage alloc] initWithSize:NSMakeSize(16, 16)]);
[container_ setSuggestionWithVerticallyCompactText:@"suggest"
horizontallyCompactText:@"suggest"
icon:nil
maxWidth:200];
[container_ showInputField:@"input" withIcon:icon];
[view_ setFrameSize:[container_ preferredSize]];
[container_ performLayout];
// Point not touching any subviews, in |view_|'s coordinate system.
NSPoint point_outside_subviews =
NSMakePoint(NSMinX([view_ bounds]), NSMaxY([view_ bounds]) - 1);
NSPoint point_inside_text_view = NSZeroPoint;
// hitTests on all inputs should be false, except for the inputField.
for (id field_view in [view_ subviews]) {
// Ensure |point_outside_subviews| really is outside subviews.
ASSERT_FALSE([field_view hitTest:point_outside_subviews]);
// Compute center of |field_view| in |view_|'s parent coordinate system.
NSPoint point =
[view_ convertPoint:NSMakePoint(NSMidX([field_view frame]),
NSMidY([field_view frame]))
toView:[view_ superview]];
if (field_view == [container_ inputField]) {
point_inside_text_view = point;
EXPECT_TRUE([view_ hitTest:point]);
} else {
EXPECT_FALSE([view_ hitTest:point]);
}
}
// Mouse events directly on the main view should be ignored.
EXPECT_FALSE([view_ hitTest:
[view_ convertPoint:point_outside_subviews
toView:[view_ superview]]]);
// Mouse events on the text view's editor should propagate.
// Asserts ensure the path covering children of |inputField| is taken.
[[view_ window] makeFirstResponder:[container_ inputField]];
NSView* editorView = [view_ hitTest:point_inside_text_view];
ASSERT_NE(editorView, [container_ inputField]);
ASSERT_TRUE([editorView isDescendantOf:[container_ inputField]]);
EXPECT_TRUE(editorView);
}
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment