| OLD | NEW |
| (Empty) | |
| 1 // Copyright 2017 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. |
| 4 |
| 5 #include "chrome/browser/ui/cocoa/bubble_anchor_helper_views.h" |
| 6 |
| 7 #import <Cocoa/Cocoa.h> |
| 8 |
| 9 #include "testing/gtest/include/gtest/gtest.h" |
| 10 #include "ui/base/test/material_design_controller_test_api.h" |
| 11 #include "ui/views/bubble/bubble_dialog_delegate.h" |
| 12 #include "ui/views/test/views_test_base.h" |
| 13 #include "ui/views/widget/widget.h" |
| 14 |
| 15 namespace { |
| 16 |
| 17 // Anchor offset in screen space (origin at bottom left of screen). |
| 18 constexpr int kHorizOffset = 210; |
| 19 constexpr int kVertOffset = 320; |
| 20 |
| 21 class TestBubbleDialogDelegateView : public views::BubbleDialogDelegateView { |
| 22 public: |
| 23 explicit TestBubbleDialogDelegateView(views::BubbleBorder::Arrow arrow) |
| 24 : BubbleDialogDelegateView(nullptr, arrow) { |
| 25 set_close_on_deactivate(false); |
| 26 set_shadow(views::BubbleBorder::NO_ASSETS); |
| 27 int screen_height = NSMaxY([[[NSScreen screens] firstObject] frame]); |
| 28 SetAnchorRect(gfx::Rect(kHorizOffset, screen_height - kVertOffset, 0, 0)); |
| 29 } |
| 30 |
| 31 ~TestBubbleDialogDelegateView() override {} |
| 32 |
| 33 // BubbleDialogDelegateView overrides: |
| 34 gfx::Size GetPreferredSize() const override { return gfx::Size(200, 150); } |
| 35 |
| 36 private: |
| 37 DISALLOW_COPY_AND_ASSIGN(TestBubbleDialogDelegateView); |
| 38 }; |
| 39 |
| 40 NSWindow* ShowAnchoredBubble(NSWindow* parent, |
| 41 views::BubbleBorder::Arrow arrow) { |
| 42 TestBubbleDialogDelegateView* bubble = |
| 43 new TestBubbleDialogDelegateView(arrow); |
| 44 bubble->set_parent_window([parent contentView]); |
| 45 views::BubbleDialogDelegateView::CreateBubble(bubble); |
| 46 bubble->GetWidget()->Show(); |
| 47 KeepBubbleAnchored(bubble); |
| 48 return bubble->GetWidget()->GetNativeWindow(); |
| 49 } |
| 50 |
| 51 } // namespace |
| 52 |
| 53 using BubbleAnchorHelperViewsTest = views::ViewsTestBase; |
| 54 |
| 55 // Test that KeepBubbleAnchored(..) actually keeps the bubble anchored upon a |
| 56 // resize of the parent window. |
| 57 TEST_F(BubbleAnchorHelperViewsTest, AnchoringFixed) { |
| 58 // Use MD anchoring since the arithmetic is simpler (no arrows). |
| 59 ui::test::MaterialDesignControllerTestAPI md_test_api( |
| 60 ui::MaterialDesignController::MATERIAL_NORMAL); |
| 61 md_test_api.SetSecondaryUiMaterial(true); |
| 62 |
| 63 // Released when closed. |
| 64 NSRect parent_frame = NSMakeRect(100, 200, 300, 400); |
| 65 NSWindow* parent = |
| 66 [[NSWindow alloc] initWithContentRect:parent_frame |
| 67 styleMask:NSBorderlessWindowMask |
| 68 backing:NSBackingStoreBuffered |
| 69 defer:NO]; |
| 70 [parent makeKeyAndOrderFront:nil]; |
| 71 |
| 72 NSWindow* child = ShowAnchoredBubble(parent, views::BubbleBorder::TOP_RIGHT); |
| 73 |
| 74 // Anchored TOP_RIGHT, so Max X/Y should be anchored. |
| 75 EXPECT_EQ(kHorizOffset, NSMaxX([child frame])); |
| 76 EXPECT_EQ(kVertOffset, NSMaxY([child frame])); |
| 77 |
| 78 // Resize the parent from the top right. |
| 79 parent_frame.size.width += 50; |
| 80 parent_frame.size.height += 60; |
| 81 [parent setFrame:parent_frame display:YES animate:NO]; |
| 82 EXPECT_EQ(kHorizOffset + 50, NSMaxX([child frame])); |
| 83 EXPECT_EQ(kVertOffset + 60, NSMaxY([child frame])); |
| 84 |
| 85 // Resize from the bottom left (no change). |
| 86 parent_frame.size.width -= 50; |
| 87 parent_frame.size.height -= 60; |
| 88 parent_frame = NSOffsetRect(parent_frame, 50, 60); |
| 89 [parent setFrame:parent_frame display:YES animate:NO]; |
| 90 EXPECT_EQ(kHorizOffset + 50, NSMaxX([child frame])); |
| 91 EXPECT_EQ(kVertOffset + 60, NSMaxY([child frame])); |
| 92 |
| 93 // Move the window. |
| 94 parent_frame = NSOffsetRect(parent_frame, -50, -60); |
| 95 [parent setFrame:parent_frame display:YES animate:NO]; |
| 96 EXPECT_EQ(kHorizOffset, NSMaxX([child frame])); |
| 97 EXPECT_EQ(kVertOffset, NSMaxY([child frame])); |
| 98 [child close]; |
| 99 |
| 100 child = ShowAnchoredBubble(parent, views::BubbleBorder::TOP_LEFT); |
| 101 |
| 102 // Anchored TOP_LEFT, so MinX / MaxY should be anchored. |
| 103 EXPECT_EQ(kHorizOffset, NSMinX([child frame])); |
| 104 EXPECT_EQ(kVertOffset, NSMaxY([child frame])); |
| 105 |
| 106 // Resize the parent from right (no change). |
| 107 parent_frame.size.width += 50; |
| 108 [parent setFrame:parent_frame display:YES animate:NO]; |
| 109 EXPECT_EQ(kHorizOffset, NSMinX([child frame])); |
| 110 EXPECT_EQ(kVertOffset, NSMaxY([child frame])); |
| 111 |
| 112 // Resize the parent from the left. |
| 113 parent_frame.size.width -= 50; |
| 114 parent_frame.origin.x += 50; |
| 115 [parent setFrame:parent_frame display:YES animate:NO]; |
| 116 EXPECT_EQ(kHorizOffset + 50, NSMinX([child frame])); |
| 117 EXPECT_EQ(kVertOffset, NSMaxY([child frame])); |
| 118 |
| 119 [parent close]; // Takes |child| with it. |
| 120 } |
| OLD | NEW |